- 環境
- のWindows 7
- のVisual Studio Professionalの2013
- C#
私は、デバイスと通信アプリ、安定化電源に取り組んでいます出力電圧を制御して、出力電圧を設定または取得します。 たとえば、現在の電圧が0Vで、デバイスに10Vが設定されている場合、出力電圧 を入力電圧10Vに変更しようとします。デバイスから電圧を読み取った場合、0V、1V、2V、... 8V、9V、10Vのように徐々に時間の経過とともに上昇することがわかります。 アプリはチャートの電圧の時間経過も表示します。1つのワーカースレッドで複数の非同期タスクを実行するにはどうすればよいですか?
私は関数を実装するためのコードを書いています。コードにwhileループがあり、電圧を得て連続的にグラフに表示します。 だから、私は非同期プログラミングを使って応答性を高めました。実際のコードの簡略化されたバージョンを次に示します。
private bool loop_flag = true;
private System.IO.Ports.SerialPort sp = new SerialPort();
private async Task measurement()
{
Open_serial_port();
loop_flag = true;
var sw = new Stopwatch();
while (loop_flag)
{
double voltage = await Task.Run(() => Get_voltage_from_device());
Update_chart(sw.ElapsedMilliseconds, voltage); // this updates a chart control showing the time course of the value.
}
sw.Stop();
Close_serial_port();
}
private double Get_voltage_from_device()
{
return Parse_bytes_into_voltage(Exec_command("get voltage"));
}
private void button_set_voltage_Click(object sender, EventArgs e)
{
Exec_command("set voltage " + textBox_voltage.Text);
}
private void button_stop_Click(object sender, EventArgs e)
{
loop_flag = false;
}
private byte[] Exec_command(string command)
{
sp.DiscardInBuffer();
sp.DiscardOutBuffer();
Send_command_using_serialport(command); // uses SerialPort.Write() method
var received_data_raw = new List<byte>();
var sw = new Stopwatch();
sw.Start();
// since data from the device may be received in several parts
// getting data repeatedly using while loop is necessary
// this loop usually takes about 20 msec to finish
while (true)
{
if (sw.ElapsedMilliseconds > 1000) // 1000 can be anything not too large or small.
{
throw new TimeoutException();
}
if (sp.BytesToRead == 0) // the buffer is often empty
continue;
while (sp.BytesToRead > 0)
{
received_data_raw.Add((byte)sp.ReadByte());
}
if (received_data_raw.Count == 1 && received_data_raw.ToArray()[0] == 0xFF) // 0xFF means the voltage was set successfully.
break;
if (received_data_raw.Count == 2) // all the data for voltage were received
break;
}
sw.Stop();
return received_data_raw.ToArray();
}
ただし、1つの問題が発生しました。 電圧を取得するコマンドがデバイスに送信され、プログラムが応答を待っているときに、デバイスに電圧を設定する新しいコマンドが送信された場合は、 デバイスはメッセージを正しく処理できず、 バイト配列。それはデバイスの仕様のように思えるので、変更することはできません。
この問題を回避するには、非同期のコマンドを送信するメソッドを1つのスレッドで実行し、 を1つずつ処理する必要があります。しかし、StackOverflowでのグーグルと検索では、私には有用な情報はありませんでした。 これを達成するにはどうすればよいですか?前もって感謝します。
あなたは単純なシングルユーザーデスクトップアプリケーションを持っているように見えるので、フェッチしようとしている間に電圧を設定するユーザーの機能を削除してみませんか? – JSteward
実際には、このアプリの機能の1つは、入力設定点にどれくらい早く応答できるかを測定することです。そのため、測定中に設定値をデバイスに送信する必要があります。申し訳ありませんが、私は説明している必要があります。 – dixhom