サブスレッドでコントロールを操作するときの注意点
スレッドでコントロールを操作するときは、コントロールを生成したスレッド
からアクセスしないといけません。(スレッドセーフ)
はてな?な方はこちら↓をどうぞ。
[関連記事] サブスレッドでコントロールを操作するには? 上のような方法で、コントロールを生成したスレッドへ処理を移すわけですが スレッドセーフだから大丈夫と思っていると痛い目にあうかも。 今回はそのお話です。 例をあげながら進めていきます。 処理の流れはこんな感じです。 1.FormAからShowメソッドでFormBを表示します。 2.FormBのLoadイベントでサブスレッドを生成、開始します。 3.処理2のスレッド内部の処理はSleepメソッドで10秒間停止し、 その後、スレッドセーフでFormBのラベルに「スレッド終了」 を設定します。 4.FormBを閉じます。 何が言いたいのか、薄々お分かりの方はいらっしゃると思いますが、、 この一連の流れでは、問題ありませんが、一部処理の流れを変えると極まれに例外が発生します。 閉じられたストリームやレジストリ キーなど、破棄されたオブジェクトを操作しようとすると ObjectDisposedException 例外がスローされます。 サブスレッド動作中に画面を閉じると、このような例外が発生する場合があります。 当初、Invokeメソッドの前に破棄されてるかどうかチェックすればよいと考えていましたが、どうやら無理のよう・・・。 Invoke直前では破棄されてないと判定されてるのが、呼び出した瞬間に例外が発生、プロパティを見ると破棄されてる・・・。 以下の条件に当てはまる場合、このような現象が発生するので注意してください。 1.フォーム上からサブスレッドを動作させている。 2.サブスレッドの処理にInvokeメソッドを使用している。 3.画面を閉じてもサブスレッドが動いている。 スレッドって難しいね。 |