dポイントプレゼントキャンペーン実施中!

下記はスレッドの中で永久ループさせるテストプログラムで、1秒毎にテキストボックス内の数値をインクリメントします。

【問題点1】
※1と※2のコマンドを削除した状態(※3のみ)で正常な動作を期待していたのですが、実際にはフリーズ状態となり、カウント値が表示されません。

※2のApplication.DoEvent()を実装するか、※3の替わりに※1に実装すると正常動作となります。

ExecThread実行中は他の処理を出来なくても、これを抜けた時点で表示処理に移るので表示される筈と思っていたのですが違う様です。

【問題点2】
Invokeの替わりにBeginInvokeを使えばExecThread実行中でも他の処理と並列処理されると思っていたのですが、スレッドを2個用意して試したところInvokeと全く変わらず、やはりフリーズ状態となります。

【問題点3】
ExecThreadを匿名メソッドにすると「フィールド初期化子は、静的でないフィールド、メソッド、又はプロパティ'iCount'を参照できません」のエラーとなり、「iCount」をstatic変数にするとOKになります。
匿名メソッドではインスタンス変数は使えないのでしょうか。

上記3項目についてネットで調べたのですがその様な記述は見当たりませんでした。

何か使い方が間違っているのでしょうか?
間違い点など、ご指摘頂ければ有難いです。 どうぞ宜しくお願いします。

private void ExecWorker() ← スレッド
{
  while (true)
  {
    Invoke(new Exec1Delegate(this.ExecThread)); ← BeginInvokeを使っても症状は同じ
    iCount++;
    Thread.Sleep(1000); ← ※1 このSleepが無いとフリーズする
    Application.DoEvent(); ← ※2 これがあると※1のSleepが無くてもOK
  }
}

delegate void ExecDelegate();
private void ExecThread()
{
  lbThread.Text = iCount.ToString(); ← 匿名メソッドにするとエラーになる
  Thread.Sleep(1000); ← ※3 (※1のSleepと同時実装はしない)
}

A 回答 (2件)

WinFormsとマルチスレッドについて詳しく書いてある書籍などを私は知らないのですが……。




とりあえず,「とあるコンサルタントのつぶやき」 ( http://blogs.msdn.com/b/nakama/ ) の一連の記事などは読んでおくとよいと思います。

・マルチスレッド Windows フォームアプリケーションの開発
http://blogs.msdn.com/b/nakama/archive/2009/03/3 …
・Part 1. Windows フォームのマルチスレッド処理の基礎
http://blogs.msdn.com/b/nakama/archive/2009/03/3 …
・タスクスレッドの起動方法
http://blogs.msdn.com/b/nakama/archive/2009/04/0 …
・Part 3. タスクスレッドと UI の協調動作
http://blogs.msdn.com/b/nakama/archive/2009/04/0 …
・Part 4. Visual Studio によるマルチスレッドアプリの開発
http://blogs.msdn.com/b/nakama/archive/2009/04/0 …
    • good
    • 0

基本的に,Invokeは


・元のスレッドをブロックする
・UIスレッドがアイドル状態になったタイミングでデリゲートを実行する
・UIスレッドでのデリゲートの実行が終了した時点で元のスレッドを再開する
という動作になります。


※1を削除すると,ワーカースレッド側で常にInvokeを呼び出すため,
メッセージに応答はしているものの常にInvokeで呼ばれたメソッドを実行している状態に近くなり,
UIの応答が極端に悪くなります。
※1によるSleepは,UIスレッドでの実行間隔を調整することになるため,応答性がよくなる効果をもたらします。


※2はやってはいけません。
Application.DoEvents自体,根本的に使うべきでは無いですし,UIスレッドで使うべき物です。


※3もやってはいけません。
UIスレッドをブロックします。


InvokeのかわりにBeginInvokeを使った場合,元のスレッドをブロックしなくなります。
※1が無い場合,全体として悪化することになります。
これは,ブロックされなくなった結果,UIスレッドにBeginInvokeのリクエストが溜まっていく結果になるためです。
    • good
    • 0
この回答へのお礼

ご丁寧な回答をいただき、有り難うございました。

もっと詳しく勉強したいのですが、お教え頂いたことを解説しているURLか書籍を御存知でしたら紹介して頂けないでしょうか。

お礼日時:2012/04/13 13:16

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!