かみやんの技術者ブログ

主にプログラムの話です

C# SerialPortのClose()でフリーズ

PC側の制御ソフトのAibiUI。去年に作成したときから、SerialPortにデータが来ている状態でアプリを終了するとフリーズすることがあった。デバッガでは、SerialPort.Close()メソッドでブロックしていることは分かっていたが、気になっていたものの直していなかった。
てっきりSerialPortの使い方の問題かと思って、Close()前にイベントハンドラをはずしたり、DiscardInBuffer()等で、シリアルポートのバッファをクリアしたりしてみたがフリーズは直らず。
調べてみたところ
http://social.msdn.microsoft.com/Forums/ja-JP/csharpgeneralja/thread/b055413b-6841-4ecc-b105-ca0cb2299d0c
同じ問題が、投稿されていて、解決していた。
結果的に、シリアルポート経由できたデータはAibiUIでは、テキストエリアに表示していたのだが、そこでメインスレッドへInvoke()しているのだが、それをBeginInvoke()にしたら直りました。
結局のところ、シリアル受信イベントでテキストエリアへの書き込みをするときに、Invoke()をするもののメインスレッド側のFormが閉じられていてInvoke()できないということであろう。Invoke()はブロッキングするが、BeginInvoke()はブロッキングしないのでOKということだろう。

1年間気になっていたバグが直ってよかった。