135

Control.Invoke 内でデリゲートを匿名で呼び出す構文に少し問題があります。

私たちはさまざまなアプローチを試みましたが、すべて役に立ちませんでした。

例えば:

myControl.Invoke(delegate() { MyMethod(this, new MyEventArgs(someParameter)); }); 

someParameter はこのメソッドに対してローカルです

上記はコンパイラ エラーになります。

デリゲート型ではないため、匿名メソッドを「System.Delegate」型に変換できません

4

8 に答える 8

228

Invoke/は(型指定されたデリゲートではなく)BeginInvoke受け入れるため、作成するデリゲートの型をコンパイラに伝える必要があります。(2.0) または(3.5) は一般的な選択肢です (署名が同じであることに注意してください)。そのようです:DelegateMethodInvokerAction

control.Invoke((MethodInvoker) delegate {this.Text = "Hi";});

パラメータを渡す必要がある場合は、「キャプチャされた変数」がその方法です。

string message = "Hi";
control.Invoke((MethodInvoker) delegate {this.Text = message;});

(警告: キャプチャasyncを使用する場合は少し注意する必要がありますが、同期は問題ありません。つまり、上記は問題ありません)

別のオプションは、拡張メソッドを記述することです。

public static void Invoke(this Control control, Action action)
{
    control.Invoke((Delegate)action);
}

それから:

this.Invoke(delegate { this.Text = "hi"; });
// or since we are using C# 3.0
this.Invoke(() => { this.Text = "hi"; });

もちろん、次の方法でも同じことができますBeginInvoke

public static void BeginInvoke(this Control control, Action action)
{
    control.BeginInvoke((Delegate)action);
}

C# 3.0 を使用できない場合は、おそらくForm基本クラスで、通常のインスタンス メソッドを使用して同じことを行うことができます。

于 2008-10-31T10:56:33.820 に答える
51

実際には、delegate キーワードを使用する必要はありません。パラメータとしてラムダを渡すだけです:

control.Invoke((MethodInvoker)(() => {this.Text = "Hi"; }));
于 2008-10-31T11:00:53.920 に答える
17
myControl.Invoke(new MethodInvoker(delegate() {...}))
于 2008-10-31T10:55:45.210 に答える
13

デリゲート型を作成する必要があります。匿名メソッド作成のキーワード「delegate」は少し誤解を招きます。匿名のデリゲートではなく、匿名のメソッドを作成しています。作成したメソッドはデリゲートで使用できます。このような:

myControl.Invoke(new MethodInvoker(delegate() { (MyMethod(this, new MyEventArgs(someParameter)); }));
于 2008-10-31T10:56:02.010 に答える
8

完全を期すために、これは Action メソッドと匿名メソッドの組み合わせによっても実現できます。

//Process is a method, invoked as a method group
Dispatcher.Current.BeginInvoke((Action) Process);
//or use an anonymous method
Dispatcher.Current.BeginInvoke((Action)delegate => {
  SomeFunc();
  SomeOtherFunc();
});
于 2010-12-20T22:16:32.787 に答える
5

メソッドから値を返すことがあるため、他の提案に問題がありました。戻り値で MethodInvoker を使用しようとすると、気に入らないようです。したがって、私が使用するソリューションは次のとおりです(これをより簡潔にする方法を聞いて非常に満足しています-私はc#.net 2.0を使用しています):

    // Create delegates for the different return types needed.
    private delegate void VoidDelegate();
    private delegate Boolean ReturnBooleanDelegate();
    private delegate Hashtable ReturnHashtableDelegate();

    // Now use the delegates and the delegate() keyword to create 
    // an anonymous method as required

    // Here a case where there's no value returned:
    public void SetTitle(string title)
    {
        myWindow.Invoke(new VoidDelegate(delegate()
        {
            myWindow.Text = title;
        }));
    }

    // Here's an example of a value being returned
    public Hashtable CurrentlyLoadedDocs()
    {
        return (Hashtable)myWindow.Invoke(new ReturnHashtableDelegate(delegate()
        {
            return myWindow.CurrentlyLoadedDocs;
        }));
    }
于 2008-11-12T22:22:50.417 に答える