C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: 受信イベントでReadExistingがタイムアウト


(過去ログ 158 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■91306 / inTopicNo.1)  受信イベントでReadExistingがタイムアウト
  
□投稿者/ ゆ牛 (7回)-(2019/06/14(Fri) 14:53:06)

分類:[.NET 全般] 

Data&#8203;Receivedイベント内でReadExistingメソッドが
タイムアウトすることがWindowsのイベントログに残りました。
現象を確認しようとしていますが再現がさせられません。
ご指導ください。

■通信概要
相手局から送られるデータを受け取り処理します。
データは$で始まりCR(0Dh)で終わる文字列。
長さはまちまちで3〜20バイト程度。
送られる間隔もまちまちで100〜200ms。
通信設定:115200bps,8bit,1stop,NoParity

■受信処理
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    data = ((SerialPort)sender).ReadExisting();  // TimeoutException発生箇所

    // dataの処理(略)
}

■推定要因
何らかの理由でDataReceivedイベントに遅れが生じ
バッファに溜まった複数のデータをReadExistingで処理した。
そうすると、次回DataReceivedが呼ばれたときには
バッファにデータが残っておらずTimeoutExceptionが発生する。
という筋書きです。

■試したこと

// 「DataReceivedイベントの遅れ」を強制的に生じさせるため
// DataReceivedを抜ける前にDelayを追加
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    data = ((SerialPort)sender).ReadExisting();  // ここでTimeoutException発生

    // dataの処理(略)

    Thread.Sleep(1000);  // Delay
}

■結果
現象再現しませんでした。
ReadExistingで複数データの処理はされましたが
次のイベントが入ってきません。
上記考えは間違っていますでしょうか?
ほかに考えられる要因はありますでしょうか?
よろしくお願いします。

■環境
Visual Studio 2010
.NET Framework 4


引用返信 編集キー/
■91320 / inTopicNo.2)  Re[1]: 受信イベントでReadExistingがタイムアウト
□投稿者/ kiku (91回)-(2019/06/16(Sun) 13:36:49)
イベントは発生するが、バッファが空になる現象を再現させることは
難しいと思いますが、実際に発生しているのでしょう。

バッファが空な状態でReadExistingを実行すると
TimeoutExceptionが発生することだけは確認できると思います。
※実験していません。

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
 data = ((SerialPort)sender).ReadExisting();

 data = ((SerialPort)sender).ReadExisting(); // ここでTimeoutException発生
}

対処方法ですが、BytesToReadなどでバッファが空であるかチェックすれば良いと思います。
引用返信 編集キー/
■91343 / inTopicNo.3)  Re[2]: 受信イベントでReadExistingがタイムアウト
□投稿者/ ゆ牛 (9回)-(2019/06/17(Mon) 17:15:57)
No91320 (kiku さん) に返信

> 対処方法ですが、BytesToReadなどでバッファが空であるかチェック…

対処法としては、
事前にBytesToReadにてバッファをチェックし、空であればReadExistingを呼ばない
という処置にしました。

> private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
> {
>  data = ((SerialPort)sender).ReadExisting();
> 
>  data = ((SerialPort)sender).ReadExisting();  // ここでTimeoutException発生
> }

実験したところ、ふたつめのReadExistingでTimeoutExceptionは発生せず
dataにカラ文字列が戻りました。
どうやら、ReadExistingはTimeoutExceptionが起きない仕様のようです。

> イベントは発生するが、バッファが空になる現象を再現させることは
> 難しいと思いますが…

色々試しましたが、バッファが空の状態でDataReceivedイベントが呼ばれる事象を
再現させることはできませんでした。
DataReceived内でバッファを読み出すと、次の受信がされるまでは
DataReceivedイベントが呼ばれない仕組みのように思えます。

kiku さん、どうもありがとございました。


引用返信 編集キー/
■91367 / inTopicNo.4)  Re[3]: 受信イベントでReadExistingがタイムアウト
□投稿者/ kiku (94回)-(2019/06/18(Tue) 18:10:31)

> どうやら、ReadExistingはTimeoutExceptionが起きない仕様のようです。

MSサイトのReadExistingには、TimeoutExceptionが発生する記述はないのですが、
StackOverFlowには、TimeoutExceptionが発生する記事を見かけました。

どっちが正しいのやら、わかりませんね。

ただイベントログに残っていることは事実であるので、
StackOverFlowの記事が正しいのではないかと思います。

よって、BytesToReadでバッファが空かどうかのチェックをするように提案しました。
この対処で、現象が発生しなくなればいいのですが、、、、
引用返信 編集キー/
■91428 / inTopicNo.5)  Re[4]: 受信イベントでReadExistingがタイムアウト
□投稿者/ ゆ牛 (10回)-(2019/06/25(Tue) 09:56:59)
No91367 (kiku さん) に返信

> よって、BytesToReadでバッファが空かどうかのチェックをするように提案しました。
> この対処で、現象が発生しなくなればいいのですが、、、、

ご配慮ありがとうございます。

この対処で、現象がおさまることを期待しますが、その一方で
別の何かの問題が潜在したままになるかもしれない不安も残ります。

> StackOverFlowには、TimeoutExceptionが発生する記事を見かけました。

差し支えなければ、この記事のURL等を教えていただけますでしょうか。


引用返信 編集キー/
■91429 / inTopicNo.6)  Re[5]: 受信イベントでReadExistingがタイムアウト
□投稿者/ kiku (97回)-(2019/06/25(Tue) 10:48:24)
> 差し支えなければ、この記事のURL等を教えていただけますでしょうか。

当時見た記事を探したのですが
見つけられませんでした。
勘違いしていたのかもしれません。
すみません。
見つけたときにURL貼っておけばよかった。

Stackoverflowで「ReadExisting TimeoutException」キーワードで検索してみてください。
複数ヒットします。
数件みたところ、TimeoutExceptionが発生するという記述はありませんでしたが、
TimeoutExceptionが発生することを前提としてcatchしているソースが
いくつかありました。

引用返信 編集キー/
■91430 / inTopicNo.7)  Re[6]: 受信イベントでReadExistingがタイムアウト
□投稿者/ ででで (3回)-(2019/06/25(Tue) 11:27:47)
2019/06/25(Tue) 11:29:41 編集(投稿者)
2019/06/25(Tue) 11:29:08 編集(投稿者)

リファレンスソースを見るとinternalSerialStream.Read内でTimeoutExceptionを発生させています。
https://referencesource.microsoft.com/#System/sys/system/io/ports/SerialPort.cs,dc72f7bc0cb07f60
引用返信 編集キー/
■91447 / inTopicNo.8)  Re[7]: 受信イベントでReadExistingがタイムアウト
□投稿者/ ゆ牛 (11回)-(2019/06/28(Fri) 10:23:25)
リファレンスソースを確認したところ
SerialStream クラスの
Read([In, Out] byte[] array, int offset, int count, int timeout) の中で
TimeoutException を throw してる箇所がありました。

これが生じる原因の解明はできていませんが
前述の BytesToRead の処置に加えて
ReadExisting を try catch で囲み
アプリ停止しないよう対策することにしました。

kiku さん、でででさん、情報提供ありがとうございました。
また情報の内容まで確認していただき感謝します。

ひとまず「解決済み」にさせていただきます。


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -