• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:Thread.Abortメソッド後の処理について)

Thread.Abortメソッドの使い方と注意点

このQ&Aのポイント
  • Thread.Abortメソッドは、スレッドを終了させるメソッドです。
  • Thread.Abortメソッドの実行後も、その後の処理は実行されることがあります。
  • Thread.Abortメソッドを使用する際には、注意が必要です。スレッド内での処理が完了していない場合、予期しない動作が発生することがあります。

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

  • ベストアンサー
noname#159480
noname#159480
回答No.1

pictureBox1.Image = null; のあたりでThreadID とかをデバッグ出力してみて、ThreadA のそれと比較されてはどうでしょうか。 コントロールへのアクセスでデリゲートを使ってるんでしょう。実は、その部分はThreadA で実行されてはいません。メインスレッドで実行されてます。メインスレッドのイベントハンドラのアイドルで実行されてます。 というか、たぶんバックグラウンドでメッセージポストされててキューの順番を待って実行されてます。

Meimei88
質問者

お礼

回答有難うございます. メインスレッドで実行されていたんですね. ということは,例えばthread_a.Start();後に処理があった場合,その前にデリゲート部分が実行されたらpictureBox1.Image = null;されるまでその処理に移行しないと考えてよいのでしょうか. ThreadIDを出力しようとしたのですが,ThreadId プロパティを使用するのかと思ったのですがどのように記述したらよいか分からず確認ができませんでした.こちらは現在調べていますが,説明して頂いた内容でAbortが何故想定通り動かなかったのか納得できそうです.

その他の回答 (2)

noname#159480
noname#159480
回答No.3

ANo1 です。 EndInvoke == Thread.join 同じようなものみたいですね。 非同期処理にも二種類ありまして、いわゆる別スレッドなのが定番のThread の類で、BeginInvoke はタイマー(待ち時間ゼロ、一回こっきり)のコールバック関数のようなものでメインスレッドで実行されるんです。 Thread も枯れた技術だし基本的に知っておくべきだとは思いますが、最近は全然違う書き方がいろいろあって、おすすめです。以下は別スレッドで実行されるんですよね。 Parallel.Invoke(  () => {   // 別スレッド A   Thread.Sleep(500);  },  () =>  {   // 別スレッド B   Thread.Sleep(500);  } ); // これは別スレッドA, B が終わるまでちゃんと待機 とかね。スレッドを意識しないでマルチスレッドなコーディングできるんで便利です。

参考URL:
http://code.msdn.microsoft.com/windowsdesktop/32-Parallel-af4950ae
Meimei88
質問者

お礼

遅くなってすみません。 参考にしたプログラムがスレッドを使用していたので、並列処理はスレッドでするものと思い込んでいた節があったのですが、いろいろと方法があるのですね。 Parallel.Invokeは.NET Framework 4.0以降で使用できるんですね。私の環境が.NET Framework 2.0なので反映することが出来ないのが残念ですが、大変勉強になりました。 わかりやすい説明も、有難うございました。 お陰様でThread.Abortについては解決致しましたので、一旦スレを閉じさせて頂きます。 また新しい疑問も湧いてきたのですが、スレッドが関係しているのかわからないので、また新しくスレを立てさせて頂きます。また助言頂けますと、幸いです。 回答有難うございました。

noname#159480
noname#159480
回答No.2

ANo.1 です。 Start() で実行しているように見えますが、実際に実行されるのはメインスレッドの任意のタイミングです。したがって次の処理が先に行われる可能性が大です。 IAsyncResult でもってEndInvoke() なんて感じで待機できます。 IAsyncResult ar = this.BeginInvoke(new MethodInvoker(delegate { pictureBox1.Image = null; })); this.EndInvoke(ar);

Meimei88
質問者

お礼

>>Start() で実行しているように見えますが、実際に実行されるのはメインスレッドの任意のタイミングです。したがって次の処理が先に行われる可能性が大です。 なるほど、スレッドを使っているので並列処理を期待していましたし、かつStart()を先に書いているのでスレッド内の処理が早く行われるものかと思っていました。 EndInvoke()は、mainに書くThread.joinと同じ挙動をすると考えても良いでしょうか? つまり、示してくださったコードにスレッド内を書き換えると、「EndInvokeまでの処理は確実に行われる保証がつき、スレッドstart()後に処理Aがあった場合Invoke内の処理が終わるまで処理Aは実行されない」のかということです。 調べてみると非同期処理を行うとあったのですが、見たページがすべてmain内でBeginInvokeとEndInvokeを行なっていたので分からず…。教えて頂けると嬉しいです。

関連するQ&A