• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:別スレッドとイベントの終了手順について)

別スレッドとイベントの終了手順について

このQ&Aのポイント
  • C#でフォーム上で別スレッドを起動し、イベントでメッセージを表示する方法についての質問です。
  • フォーム上でボタンを押下することで別スレッドが起動し、メッセージをテキストボックスに表示しますが、フォームの×ボタンを押下するとスレッドの停止処理中に止まってしまいます。
  • スレッド中で呼び出されているイベントが原因のようですが、終了手順の王道的な方法はありますか?

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

暇だったので検証してみたところ、デバッガで見る限りですが、 Closed(Closingの時点で既に)発生の段階で、this.Invoke(process)が硬直しているように思います。 調べてみるとこれは割と有名なことらしく、 UIのスレッド側が既に終了遷移しているためにInvokeを受けることができない状況であることが原因のようです。 条件をつけたりして細工をしたとしても低確率で再現してしまうようです。 対策としては、 ・スレッドとクラスを完全に分離する(Invokeを使用しない)。 ・BeginInvoke(非同期実行)で実装する。 ・Closing発生時にLoopスレッドをAbortする。 くらいでしょうか。

ctmogawa
質問者

お礼

すみません、補足で書いてしまい、お礼を忘れておりました。 改めてお礼とさせて頂きます。 ありがとうございました。

ctmogawa
質問者

補足

検証、ありがとうございます。   this.Invoke( process ); を   this.BeginInvoke( process ); にすることでフォームの×ボタン押下でも終了するようになりました。 非同期にする事で最後の問題となるInvokeがどのように処理されているのか 気にはなるところですが、動作としてはエラーもなく正常に終了しましたの で、今回の対策で様子を見たいと思います。 ちなみに、Trhred.Abort();でも終了できました。

その他の回答 (1)

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.1

C#はよく知らないのですが、スレッドの終わらせ方としては、そんな感じで普通かなと思いました。 ちなみにこれ、×ボタンで閉じた時だけ起こりますか? タイミングによっては、ボタン2を押した時にも起こりそうな気がします。 予想ですが、Invokeという関数は、UI側のスレッドの実行が完了するまで、 制御が戻らない、同期型の動作をする関数ではないでしょうか? もしそうだとすると、UIスレッドがJoinでワーカースレッドの完了を待ち、 ワーカースレッドは、UIスレッドがテキストを更新するのを待ち、 というデッドロック状態になっているのではないかと思います。 Invokeが同期型なら、それの非同期版の関数が用意されているような気もしますが、 そういうものがあるかどうかはわからないので、その点については回答を控えます。

ctmogawa
質問者

お礼

情報ありがとうございます。 今回は非同期型のBeginInvoke()で対応しましたが、デッドロックが 原因であれば他の方法もあるかもしれませんので、もう少し検証して みたいと思います。