C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: スレッドの終了


(過去ログ 71 を表示中)

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■41715 / inTopicNo.1)  スレッドの終了
  
□投稿者/ 若葉マーク (4回)-(2009/09/29(Tue) 10:16:48)

分類:[C#] 

いつも参考にさせて頂いており、ありがとうございます。

別スレッド内でのコントロールへの代入について教えて頂けないでしょうか?

フォームに貼り付けた StatusStrip に別スレッドから代入したいので Invoke を使い
下のようにコーディングしたところ、代入自体は上手くいくのですがスレッドが終了
しない場合が発生します、StatusStrip への代入処理を行わなければスレッドは直ちに
終了するようです。

なぜ、Invoke を使ったコントロールへの代入を行うとスレッドが終了しないケースが
発生するのでしょうか?

(.Net 2008)

private bool Stop = false;
private System.Threading.Thread WorkerThread;
private delegate void InvokeDelegate(object _Object);

private void Initial()
{
WorkerThread = new System.Threading.Thread(new System.Threading.ThreadStart(Worker));
WorkerThread.IsBackground = true;
WorkerThread.Start();
}

private void Worker()
{
while (Stop == false)
{
StatusStrip.Invoke(new InvokeDelegate(delegate(object _String)
{
StatusStrip.Items[0].Text = (string)_String;
}), new object[] { System.DateTime.Now.ToString("yy/MM/dd") });
System.Threading.Thread.Sleep(200);
}
}

//プログラムを終了させる
private void button1_Click(object sender, EventArgs e)
{
Stop = true;
WorkerThread.Join();
this.Dispose();
}
}

引用返信 編集キー/
■41721 / inTopicNo.2)  Re[1]: スレッドの終了
□投稿者/ なちゃ (330回)-(2009/09/29(Tue) 10:45:31)
デッドロックです。
StopをTrueにしたとき、スレッド側がInvokeの前辺りにいたとするとどうなるでしょうか?
直後にInvokeが実行されますが、画面のスレッドはもはやJoinに入って止まるだけですから、
いつまでも待っても画面処理が出来ません。

画面処理が出来ないため、Invokeは永久に返ってきません。
スレッド側が永久に終わりませんから、Joinも永久に返ってきません。

引用返信 編集キー/
■41722 / inTopicNo.3)  Re[2]: スレッドの終了
□投稿者/ なちゃ (331回)-(2009/09/29(Tue) 10:57:38)
簡単に対処するなら、InvokeではなくBeginInvokeにして、BeginInvoke内の最初でもStopがfalseかを確認して、falseの時だけ画面処理すればいいでしょう。

引用返信 編集キー/
■41726 / inTopicNo.4)  Re[2]: スレッドの終了
□投稿者/ 若葉マーク (5回)-(2009/09/29(Tue) 11:27:57)
No41721 (なちゃ さん) に返信
> デッドロックです。
> StopをTrueにしたとき、スレッド側がInvokeの前辺りにいたとするとどうなるでしょうか?
> 直後にInvokeが実行されますが、画面のスレッドはもはやJoinに入って止まるだけですから、
> いつまでも待っても画面処理が出来ません。
>
> 画面処理が出来ないため、Invokeは永久に返ってきません。
> スレッド側が永久に終わりませんから、Joinも永久に返ってきません。
>
なちゃさんありがとうございます。
ご指摘の通り Invoke の処理が終わってから Join を実行するように修正すれば上手くいきました。
ただ修正の方法があまいのか Join で別スレッドの処理の終了待機する必要がなくなってしまいました
行った修正は別スレッドの While ループを抜けたときにフラグをセットするようにし、ボタンの
クリックイベント内でそのフラグの監視を行うようにしました。
(もっと効率の良い方法があるのかも知れませんがこれしか思い当たりませんでした)

Join の説明には「1つのスレッドが終了するまで呼び出し元のスレッドをブロックします。」と
ありますが Join 以降の親スレッドの実行が停止するだけでなく、このような画面を含めた
コントロールの更新もブロックされてしまうのですね。

ありがとうございました
解決済み
引用返信 編集キー/
■41728 / inTopicNo.5)  Re[3]: スレッドの終了
□投稿者/ 渋木宏明(ひどり) (1231回)-(2009/09/29(Tue) 12:19:14)
渋木宏明(ひどり) さんの Web サイト
BackgroundWorker コンポーネントを使えばいいのでは?

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -