2012-04-24 10 views
2

非同期のOnMsgRecieved呼び出しで、値をコントロールに直接割り当てると、コントロールに機能しません。 その後、スレッドが安全でないことが判明し、問題を解決するためにコードを取得しました。 これは機能しています。しかし、私はそれが実際に何をしているのか分かりません。誰も私にそれを完全に理解させることができますか? コードは: -Windowsフォームスレッドではどういうことが起こっていますか?

 public void listener_OnMsgRecieved(string aResponse) 
    { 
     ShowResponseMessage(aResponse); 
    } 

    public void ShowResponseMessage(string aResponse) 
    { 
     // InvokeRequired required compares the thread ID of the 
     // calling thread to the thread ID of the creating thread. 
     // If these threads are different, it returns true. 
     if (this.listBox.InvokeRequired) 
     { 
      SetTextCallback d = new SetTextCallback(ShowResponseMessage); 
      this.Invoke(d, new object[] { aResponse }); 
     } 
     else 
     { 
      this.listBox.Items.Add(aResponse); 
      label.Text = "Response received from Server :"; 
     } 
    } 

答えて

1

InvokeRequiredは、あなたがWindowsメッセージキューにメッセージを送信するためにControl.Invokeを使用している、trueを返します。

UIスレッドで実行されるUIメッセージポンプがメッセージをプルしてターゲットコントロールに配信すると、ターゲットコントロールは、これがデリゲートが呼び出され、デリゲートがコントロールによって呼び出されることを要求するメッセージであることを確認しますこれはUIスレッド上で実行されているため、クロススレッドの問題は解決されています。

トリックは、デリゲートが非UI呼び出しスレッドで直接呼び出されないことです。 Windowsメッセージを使用して、デリゲートを実行するための命令がUIスレッドに渡され、UIスレッドはメッセージに応答してデリゲートを実行します。 'Control.Invoke'はWindows [SendMessage][1]を使用し、Control.BeginInvoke[PostMessage][2] Win32 APIを使用してメッセージの受け渡しを容易にします。

+0

同期コンテキストに関連するものはありますか? – userGS

+0

ありがとう、実用的な説明! –

0

UIコントロールを更新/メインスレッドは/それが作成されたスレッド以外の任意のスレッドから変更することはできません。

あなたの場合、チェックInvokeRequiredはコントロールを変更したいスレッドが作成スレッドであるかどうかを確認し、そうでない場合はメインスレッド/作成者にコールを戻します。

は、あなたのWindows Formsアプリケーションのパフォーマンスを向上させるためにマルチスレッドを使用する場合は、あなたがスレッドセーフな方法であなたの コントロールへの呼び出しを行うことを確認する必要がありますHow to: Make Thread-Safe Calls to Windows Forms Controls

を見てみましょう。

Windowsフォームコントロールへのアクセスは、本質的にスレッドセーフではありません。 に2つ以上のスレッドがコントロールの状態を操作している場合は、コントロールを一貫性のない状態に強制することが可能です( )。競合状態や デッドロックなどのその他の スレッド関連のバグが可能です。コントロール へのアクセスがスレッドセーフな方法で実行されることを確認することが重要です。

Invokeメソッドを使用せずにコントロールを作成したスレッド以外のスレッドからコントロールを呼び出すことは安全ではありません。 ShowResponseMessageはUIとは異なるスレッドで呼び出された場合

関連する問題