27

C#2.0とMethodInvokerデリゲートを使用して、GUIスレッドまたはワーカースレッドからイベントを受信するGUIアプリケーションがあります。

次のパターンを使用して、フォームでイベントを処理します。

private void SomeEventHandler(object sender, EventArgs e)
{
    MethodInvoker method = delegate
        {
            uiSomeTextBox.Text = "some text";
        };

    if (InvokeRequired)
        BeginInvoke(method);
    else
        method.Invoke();
}

このパターンを使用することで、実際のUIコードを複製しませんが、この方法が適切かどうかはわかりません。

特に、ライン

method.Invoke()

呼び出すために別のスレッドを使用しますか、それともGUIスレッドのメソッドへの直接呼び出しにいくらか変換されますか?

4

5 に答える 5

22

呼び出しはmethod.Invoke()、現在実行中のスレッドでデリゲートを実行します。を使用BeginInvoke(method)すると、デリゲートがGUIスレッドで呼び出されるようになります。

これは、GUIスレッドと他のスレッドの両方から同じメソッドを呼び出すことができる場合にコードの重複を回避する正しい方法です。

于 2009-04-23T15:33:27.627 に答える
15

個人的に私はこの方法が好きです:

private void ExecuteSecure(Action a)
{
    if (InvokeRequired)
        BeginInvoke(a);
    else
        a();
}

そして、次のようなワンライナーを書くことができます。

ExecuteSecure(() => this.Enabled = true);
于 2011-11-05T15:06:42.340 に答える
5

バックグラウンドスレッドを使用していて、Control.IsHandleCreatedがfalseの場合、Control.InvokeRequiredはfalseを返すことに注意してください。アンマネージドハンドルの作成をチェックするDebug.Assertを使用してコードを保護します。

于 2009-04-28T18:01:03.753 に答える
2

WinFormsの場合、呼び出しControl.Invoke(Delegate)はUIのtheadのメッセージポンプにメッセージを送信します。次に、スレッドはメッセージを処理し、デリゲートを呼び出します。処理が完了するInvokeと、ブロックが停止し、呼び出し元のスレッドがコードの実行を再開します。

于 2009-04-23T15:37:19.413 に答える
0

同じスレッドで呼び出しを行います。コードをステップスルーして確認できます。そのアプローチには何の問題もありません。

于 2009-04-23T15:32:28.317 に答える