SerialPort からデータを読み取り、バイト[]を返す関数を作成したいとしましょう。明らかに、これはSerialPortで読み取る正しい方法ではない
public byte[] RequestData(byte[] data)
{
//See code below
}
これは実際に動作しない/よく実行し、非常に信頼性がないんのような単純なもの:
while (port.BytesToRead < 14)
{
//Maybe Thread.Sleep(10) here?
}
:
byte[] response = new byte[port.ReadBufferSize];
port.Open();
port.Write(data, 0, data.Length);
Thread.Sleep(300); //Without this it doesn't even work at all
Console.WriteLine("Bytes to read: {0}", port.BytesToRead);
int count = port.Read(response, 0, port.ReadBufferSize);
Console.WriteLine("Read {0} bytes", count);
port.Close();
port.Dispose();
return response.GetSubByteArray(0, count);
を私はまた、のようなものとのThread.sleepを交換してみました
しかし、それは問題を引き起こします。 (PS:私は、少なくとも14バイトを必要と知っている)もちろん
(と思う)のようなもの持っているだろうより良い方法:
port.ReceivedBytesThreshold = 14;
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
port.Write(data, 0, data.Length);
そしてもちろんのハンドラた:
をvoid port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var port = (SerialPort)sender;
while (port.BytesToRead > 0)
{
//Read the data here
}
}
しかし、定義したい機能の結果としてデータを返すことはできません。 これを使用しているクライアントコードは、このコードで生成されたイベントのサブスクリプションを行う必要がありますが、 ですが、実際にはその応答が実際に要求に対する応答であることはどのように分かりますか。
(複数のメッセージが送信される可能性があり、一方のメッセージがもう一方のメッセージよりも処理に時間がかかります)
任意のアドバイスは
UPDATE
次のコードはかなり良く動作しますが、私はのThread.sleep()文を削除した場合、それが再び正常に動作を停止した歓迎されるであろう。例えば、シリアルポート監視ツールは、シリアルラインに17バイトが書き込まれていることを明確に示しています。最初のBytesToRead = 10と次回のBytesToRead = 4でしたが、BytesToReadは0のままなので、最後の3バイトはどこに行きましたか?ここで
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(100);
while (port.BytesToRead > 0)
{
Console.WriteLine("Bytes to read: {0}", port.BytesToRead);
var count = port.BytesToRead;
byte[] buffer = new byte[count];
var read = port.Read(buffer, 0, count);
if (count != read)
Console.WriteLine("Count <> Read : {0} {1}", count, read);
var collectAction = new Action(() =>
{
var response = dataCollector.Collect(buffer);
if (response != null)
{
this.OnDataReceived(response);
}
});
collectAction.BeginInvoke(null, null);
Thread.Sleep(100);
}
}
これはまだSerialPortを読む方法ではありません。 –
これは本当に今働いているからです – TimothyP
これを読んでいる人にはちょうどいいね。DataReceivedイベントは、SerialPortインスタンスを作成したスレッドとは別のスレッドで起動されます。 http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.datareceived.aspxを参照してください。 – rkagerer