本文中に誤りがありましたことをお詫びし、以下に訂正致します。

増刷分は訂正されています.

訂正ページ:P.151〜付近 3-8バウンドプログラム(正常版)

デリゲートによって、いったんメインスレッドに制御を戻し、メインスレッドから画面の更新を行います。
デリゲートによって、いったんForm1に制御を戻し、画面の更新を行います。


TOP








補足説明

スレッド間のコントロールアクセスに関してはの一章の後半に詳しい解説も記載しました.

補足 デリゲートを呼び出してもスレッドは切り替わりません..NETのコントロールはコントロール生成したスレッド以外から,そのコントロールをアクセスすることはできません.本書はオブジェクト経由で表示を行っていますので問題は生じませんが,直接,異なるスレッドからコントロールを直接操作できません.生成したスレッドと異なるスレッドからコントロールを操作するには,基本的に不可能ですので,以下の方法を勧めます.
  1. 本書のようにオブジェクトでアクセスする.
  2. メインスレッドにタイマーを用意し,そのタイマーでスレッドを監視する.ワーカスレッドの状態をメインスレッドで画面に反映する.状況により同期処理が必要な場合があるが,もっともオーソドックスな方法.
  3. 本書の例にあるメッセージを使用して,情報をワーカスレッドからメインスレッドに渡し,画面を更新する.
  4. BackgroundWorkerを使用する方法.タイマーで監視する必要も無く,完了のcall backでコントロールを操作することも可能である.ReportProgressメソッドを使えば,途中経過を表示することもできる.一般的なスレッドプログラムは,この方法で救済で来る場合が多い.
  5. 本書にもある,Queueクラスと,Monitorクラスでスレッド間通信を行い,メインスレッドで画面を更新する.
  6. デリゲートでスレッドIDが自分自身か調べ,同じでなければinvokeし,同じならコントロールに直接アクセス方法.
いずれにしても,「デリゲートによって、いったんメインスレッドに制御を戻し、メインスレッドから画面の更新を行います。」は記述間違いです.

内容は増刷の際に「メインスレッドに制御を戻し、」を適切に書き換えました.Form間の参照,スレッド間の参照で困っている人が多いことが判明しましたので,改訂時にサンプルを追加する予定です.

ワンポイント:スレッド間におけるコントロールのアクセスについて

もし、ほかのスレッドが生成したコントロールへアクセスしたい場合、一旦元のスレッドへ戻さなければなりません。このような場合、3-6に示すタイマーでワーカスレッドを監視しコントロールへアクセスする方法、3-13に示すメッセージによる方法、4-18、4-19で示すQueueクラスを用いる方法、あるいは本書では紹介していませんが、.NET 2.0で追加されたBackgroundWorkerクラスを用いる方法、あるいはデリゲートでコントロールのInvokeRequiredを調べ,同じスレッドでなければInvokeメソッドを呼び出す方法があります。

特に.NET 2.0で追加されたBackgroundWorkerを使用する方法は,スレッドの明示的な記述や.タイマーで監視する必要も無く,完了のcall backでコントロールを操作することも可能です.ReportProgressメソッドを使えば,途中経過を表示することもできます.初心者にはBackgroundWorkerを使用する方法は良い方法と思います

TOP