C# 入門 & 実践 / C sharp

501-6. スレッドセーフな呼び出し!


方法 : Windows フォーム コントロールのスレッド セーフな呼び出しを行う
http://msdn2.microsoft.com/ja-jp/library/ms171728(・・・

マルチスレッドで複数のスレッドからアクセスしてコントロールする場合に、スレッドセーフな作り?にするために
デリゲートを作成して、Invoke から呼び出す処理を入れるようです。

フォーム内のラベル等を変更処理を入れる場合

        /// 
        /// 表示内容変更
        /// 
        /// 
        /// 
        public void changeMessage(string title, string msg)
        {
                this.Text = title;
                this.label_title.Text = title;
                this.label_msg.Text = msg;
                this.Refresh();
        }
通常これだけで良いのですが、マルチスレッドで呼び出す場合は、コンパイル時警告が出ます。
もちろん、本番でもエラーに繋がる可能性が高いです。

        // スレッドセーフ用
        delegate void SetTextCallback(string title, string msg);

        /// 
        /// 表示内容変更
        /// 
        /// 
        /// 
        public void changeMessage(string title, string msg)
        {
            if (this.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(changeMessage);
                this.Invoke(d, new object[] { title, msg });
            }
            else
            {
                this.Text = title;
                this.label_title.Text = title;
                this.label_msg.Text = msg;
                this.Refresh();
            }
        }

サンプルとほぼ同じですが、こんな感じで、デリゲートを宣言しておいて
Invokeで呼び出します。

[ Control.InvokeRequired プロパティ ]

呼び出し元がコントロールの作成されたスレッドと異なるスレッド上にあるため、コントロールに対してメソッドの呼び出しを実行するときに、呼び出し元で invoke メソッドを呼び出す必要があるかどうかを示す値を取得します。
http://msdn2.microsoft.com/ja-jp/library/system.wi・・・

ということですね。



501-5. Moniterで同期管理 « マルチスレッド同期


C# 入門 & 実践 / C sharp