1

組み込みデバイスから非同期でデータを受信するシリアル ポートがあります。ユーザーはいつでもポートとの接続を終了するオプションがありますが、これは、ユーザーが送信中に切断した場合に例外が発生することを意味します (プログラムが で停止することがありますmyPort.Close())。「空になるまで待機」コマンドを追加する方法はありますか? 以下のようなものでしょうか?

private void tsDisconnect_Click(object sender, EventArgs e)
{
      try
      {
          while(myPort.BytesToRead > 0)
          {//wait here}
      }
      myPort.Close();
}
4

1 に答える 1

4

待機しても、Close() の呼び出しで発生するデッドロックは修正されません。コアの問題を修正する必要があります。ほとんどの場合、DataReceived イベント ハンドラーのコードが原因です。見ることはできませんが、よくある間違いは、Control.Invoke() または Dispatcher.Invoke() を使用することです。

イベント ハンドラーが戻るまで、シリアル ポートを閉じることはできません。しかし、Invoke() 呼び出しでスタックしているため、戻ることができません。UI スレッドがビジーであるため完了できず、Close() 呼び出しでスタックしています。または、BytesToRead が 0 になるのを待っています。これは、あなたが追求している解決策です。どちらも機能しません。DataReceived イベント ハンドラーが動かなくなり、読み取れなくなります。デッドロックシティ。

そのコードを修正し、代わりに BeginInvoke() を使用する必要があります。これは非ブロッキング呼び出しであり、デッドロックを引き起こすことはありません。

デッドロックの原因は他にも考えられます。診断が簡単で、デバッグする時間がたくさんあります:) Debug + Break Allを使用してから、Debug + Windows + Threadsを使用します。メイン スレッドをダブルクリックし、そのコール スタックを調べて、UI スレッドが何をしているかを確認します。

于 2013-07-15T17:59:17.473 に答える