3

GUI コンポーネントを別のスレッドから使​​用できないことはわかっています。したがって、通常は をチェックInvokeRequiredしてから呼び出すInvokeなどのメソッドを実行します。しかし、これは大量のコードです。そのようなことを行う方法はありますか:MyEvent += myDelegateこの myDelegate は、割り当てられたスレッドから実行されますか? ControlInvoke メソッドがクラスからのみ利用できるのはなぜですか? 私が持っている唯一のアイデアは、 AddDelegate (delegate.. , Control c) などの独自のメソッドを作成することです。

これを達成する方法はありますか?

4

4 に答える 4

4

このようなコードの繰り返しを避けるために、私は通常、このロジックを分離するクラスを作成します。アプリケーションの起動時に、このクラスを初期化し、アプリケーション全体で使用します。利点は、コントロールの外で使用できることです。

public static class UI
{
    private static Control internalControl;

    public static void Initialize(Control control)
    {
        internalControl = control;
    }

    public static void Invoke(Action action)
    {
        if (internalControl.InvokeRequired)
        {
            internalControl.Invoke(action);
        }
        else
        {
            action();
        }
    }
}

メイン フォームの初期化時に初期化します。

UI.Initialize(this);

使用法:

UI.Invoke(() => { this.Text = "Test"; });
于 2012-08-11T19:20:19.513 に答える
2

私はかなり単純な方法を使用しました:

private void execThreadSafeMethod(Control ctrl)
{
     MethodInvoker method = (MethodInvoker) delegate
     {
         //Do something that you always wanted to do :)
     }
     if(ctrl.InvokeRequired == true)
     {
          ctrl.Invoke(method);
     }
     {
          method.Invoke();
     }
}
于 2012-08-11T19:18:02.040 に答える
1

メソッドを見つけるのを待ち続けましたが、表示されません (質問を正しく読んでください)。

これは、別のスレッドで呼び出しを処理する方法です。

this.Invoke((MethodInvoker)delegate() { /*whatever I need done*/ });

これは、コードを適切な場所に置いておくことができ、飛び回ることがないため便利です。

this.Invoke((MethodInvoker)delegate() {
    //here is some code I need to run on the main thread
    //usually making a label visible or some other bs
    //might want to resize my form or update a list box, who knows
});
于 2014-04-16T20:48:01.430 に答える
1

.Net 4 を使用していますか? その場合は、非同期タスクを使用できます。

コントロールが作成されたメイン スレッドの同期コンテキストから TaskScheduler を作成します。

var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();

次に、バックグラウンド スレッドで実行されている任意のメソッドでこれを使用して、メイン スレッド上の任意のコントロールを更新できます。

Task.Factory.StartNew(
    () => { MessageBox.Show("Message from separate thread.") }, 
    CancellationToken.None, 
    TaskCreationOptions.None, 
    uiTaskScheduler);
于 2012-08-11T19:40:33.693 に答える