Invoke调用中的匿名方法

对于我们想在Control.Invoke中匿名调用委托的语法有点麻烦。

我们尝试了一些不同的方法,都无济于事。

例如:

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

someParameter是本地方法

以上将导致编译器错误:

无法将匿名方法转换为键入“System.Delegate”,因为它不是委托types

因为Invoke / BeginInvoke接受Delegate (而不是一个types化的委托),所以你需要告诉编译器什么types的委托来创build; MethodInvoker (2.0)或Action (3.5)是常用选项(注意它们具有相同的签名)。 像这样:

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

如果你需要传入参数,那么“捕获variables”是这样的:

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

(警告:如果使用捕获asynchronous ,你需要谨慎一点,但同步是好的 – 即上述情况是好的)

另一个select是写一个扩展方法:

 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基类中。

其实你不需要使用委托关键字。 只需传递lambda作为参数:

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

您需要创build一个委托types。 匿名方法创build中的关键字“委托”有点令人误解。 您不是创build一个匿名委托,而是一个匿名方法。 您创build的方法可以在委托中使用。 喜欢这个:

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

为了完整起见,这也可以通过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(); }); 

我有其他build议的问题,因为我想有时从我的方法返回值。 如果您尝试使用返回值MethodInvoker似乎并不喜欢它。 所以我使用的解决scheme是这样的(非常高兴听到一种方法来使这更简洁 – 我使用的是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; })); }