Monday, June 08, 2009

SerialPortのDataReceivedイベントについて

鈴木@KEG と申します。

だいぶ前の投稿への返信ですけど、他のみなさまのためにも。

DataRecieved イベント で、受信したバイト数を取得するには、BytesToRead プロパティを参照します。例外の補足を除いたシンプルなコードは、以下のように書けます。

if (serialPort1.BytesToRead > 0)
{
// 受信バッファからデータを取得
byte[] b = new byte[serialPort1.BytesToRead];
Read(b, 0, b.Length);
}

DataRecieved イベントを受け取った後も、刻々と受信バッファにデータが入るので、BytesToRead を参照するときには注意して下さい( 上の例だと、Read(b, 0, serialPort1.BytesToRead); はNG )。

ReadBufferSize は、バッファのサイズそのものです。また、ReceivedBytesThreshold は、受信バッファに溜まったデータが何バイトになったら、DataRecived イベントを発生させるか、といったプロパティです。初期値はいずれも 0を越えていますのでサンプルに挙げられたソースでは、常に真となってしまわれると思います。

DataRecieved イベント内の処理が多かったり、イベント内で複数回のReadを行っていると、DataRecieved イベントは受信バッファにReceivedBytesThreshold の分だけデータが溜まった時に呼ばれるので、イベントがスタックする事もあるかと思います(フロー制御を行っていると、大抵は相手の送信が止まるので確認できませんけれど)。イベントが来ることを防止するのでは無く、BytesToRead で読み取り可能なバイト数を確認する事と、Read の例外をcatch するのが良い方法だと思います。

No comments: