下記はスレッドの中で永久ループさせるテストプログラムで、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と同時実装はしない)
}
No.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 …
No.1
- 回答日時:
基本的に,Invokeは
・元のスレッドをブロックする
・UIスレッドがアイドル状態になったタイミングでデリゲートを実行する
・UIスレッドでのデリゲートの実行が終了した時点で元のスレッドを再開する
という動作になります。
※1を削除すると,ワーカースレッド側で常にInvokeを呼び出すため,
メッセージに応答はしているものの常にInvokeで呼ばれたメソッドを実行している状態に近くなり,
UIの応答が極端に悪くなります。
※1によるSleepは,UIスレッドでの実行間隔を調整することになるため,応答性がよくなる効果をもたらします。
※2はやってはいけません。
Application.DoEvents自体,根本的に使うべきでは無いですし,UIスレッドで使うべき物です。
※3もやってはいけません。
UIスレッドをブロックします。
InvokeのかわりにBeginInvokeを使った場合,元のスレッドをブロックしなくなります。
※1が無い場合,全体として悪化することになります。
これは,ブロックされなくなった結果,UIスレッドにBeginInvokeのリクエストが溜まっていく結果になるためです。
ご丁寧な回答をいただき、有り難うございました。
もっと詳しく勉強したいのですが、お教え頂いたことを解説しているURLか書籍を御存知でしたら紹介して頂けないでしょうか。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Java java 次の機能を有するメソッドを自クラスに作成し、実装したいです。 機能 名前判定機能 →名前が 3 2022/06/16 16:08
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/17 18:41
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
- Visual Basic(VBA) vba Sleep関数について教えてください 1 2023/01/18 10:18
- その他(プログラミング・Web制作) このプログラミングをどう組みますか? Googlecolabでやってるんですが、出来る方お願いします 1 2022/07/13 10:52
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- Java javaの質問です 次の機能を有するメソッド4つを自クラスに作成し、実装したいです 【機能】 足し算 1 2022/06/15 17:49
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- その他(開発・運用・管理) WindowsからSSHでサーバーにあるファイルをダウンロードできない…。 3 2022/04/24 11:08
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/06 09:28
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
tryの終了
-
doGetとdoPostの違い
-
Javaでのデバッグコード削除
-
Tomcat高負荷時の設定について
-
複数リクエストの扱い
-
ラジオボタンの選択判定
-
WPF C#でF10のイベント取得方法...
-
Javaプログラムからポップアッ...
-
数値の定数を付ける時
-
JavaでVBのDOEVENTSと同様の処...
-
VBScriptでのWord印刷
-
C#でバックグラウンド処理から...
-
Delphiのマルチスレッドの割り...
-
ラベルの表示までが異常に遅い...
-
JavaScriptからJAVAクラスを呼...
-
SwingUtilities.invokeLater(ne...
-
WaitForSingleObjectの復帰時間
-
データ未入力時のエラー処理が...
-
csvファイルを出力する簡単なプ...
-
アコーディオンメニューをアン...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
tryの終了
-
doGetとdoPostの違い
-
Javaプログラムからポップアッ...
-
SwingUtilities.invokeLater(ne...
-
Javaでのデバッグコード削除
-
Tomcat高負荷時の設定について
-
JavaScriptからJAVAクラスを呼...
-
データ未入力時のエラー処理が...
-
ブラウザを閉じた後のサーバ側...
-
アコーディオンメニューをアン...
-
[Java] while(true)の意味
-
数値の定数を付ける時
-
Javaアプリケーション実行の返...
-
スレッド1とスレッド2を交互に...
-
ラジオボタンの選択判定
-
WPF C#でF10のイベント取得方法...
-
onBlurとonFocusの処理順序につ...
-
flush()メソッドについて・・・
-
ExcelVBA で文字列の特定の文字...
-
ラベルの表示までが異常に遅い...
おすすめ情報