匿名方法作为BeginInvoke的参数?

为什么不能将匿名方法作为参数传递给BeginInvoke方法? 我有以下代码:

 private delegate void CfgMnMnuDlg(DIServer svr); private void ConfigureMainMenu(DIServer server,) { MenuStrip mnMnu = PresenterView.MainMenu; if (mnMnu.InvokeRequired) { mnMnu.BeginInvoke((CfgMnMnuDlg)ConfigureMainMenu, new object[] { server}); } else { // Do actual work here } } 

我试图避免宣布代表。 为什么我不能写下面的东西呢? 或者我可以,我只是无法弄清楚正确的语法? 以下目前生成:

参数类型’System.Delegate’不能赋予参数类型’匿名方法’

好吧,这当然是正确的,但是我可以使用其他一些语法来做到这一点(避免为了使用BeginInvoke()而声明一个单独的委托吗?

(能够做到这一点将完全符合使用anon方法/ lamdas代替显式委托的概念,这些委托在其他地方工作得非常干净。)

 private void ConfigureMainMenu(DIServer server,) { MenuStrip mnMnu = PresenterView.MainMenu; if (mnMnu.InvokeRequired) { mnMnu.BeginInvoke( // pass anonymous method instead ? delegate(DIServer svr) { ConfigureMainMenu(server);}, new object[] { server}); } else { // Do actual work here } } 

试试这个:

 control.BeginInvoke((MethodInvoker) delegate { /* method details */ }); 

要么:

 private void ConfigureMainMenu(DIServer server) { if (control.InvokeRequired) { control.BeginInvoke(new Action(ConfigureMainMenu), server); } else { /* do work */ } } 

要么:

 private void ConfigureMainMenu(DIServer server) { MenuStrip mnMnu = PresenterView.MainMenu; if (mnMnu.InvokeRequired) { // Private variable _methodInvoker = new MethodInvoker((Action)(() => ConfigureMainMenu(server))); _methodInvoker.BeginInvoke(new AsyncCallback(ProcessEnded), null); // Call _methodInvoker.EndInvoke in ProcessEnded } else { /* do work */ } } 

你应该能写出这样的东西:

 private void ConfigureMainMenu(DIServer server,) { MenuStrip mnMnu = PresenterView.MainMenu; if (mnMnu.InvokeRequired) { mnMnu.BeginInvoke(new Action(ConfigureMainMenu), new object[] { server}); } else { // Do actual work here } } 

您可以编写一个扩展方法来包装匿名方法,甚至可以处理InvokeRequired语义:

 public static void InvokeAction(this Control ctl, Action a) { if (!ctl.InvokeRequired) { a(); } else { ctl.BeginInvoke(new MethodInvoker(a)); } } 

这将允许您这样做:

 control.InvokeAction(delegate() { ConfigureMainMenu(server); }); 

您可以通过调用自己调用在单个方法中执行此操作:

  ClassData updData = new ClassData(); this.BeginInvoke(new Action(FillCurve), new object[] { updData }); 

 public void FillCurve(ClassData updData) { ... } 

对于具有有限数量参数的完全匿名方法:

 Func caller = new Func((int param1) => { return null; }); caller.BeginInvoke(7, new AsyncCallback((IAsyncResult ar) => { AsyncResult result = (AsyncResult)ar; Func action = (Func)result.AsyncDelegate; action.EndInvoke(ar); }), null); 

您可以根据需要使用其他Func委托类型之一。

我尝试过一些不同的方法但没有工作。 即…

// Fails -- cannot convert lamda to System.Delegate mnMnu.BeginInvoke( (DIServer svr)=> {ConfigureMainMenu(server);}, new object[] server); // Fails -- cannot convert anonymous method to System.Delegate mnMnu.BeginInvoke( new delegate(DIServer svr){ConfigureMainMenu(server);}, new object[] server);
// Fails -- cannot convert lamda to System.Delegate mnMnu.BeginInvoke( (DIServer svr)=> {ConfigureMainMenu(server);}, new object[] server); // Fails -- cannot convert anonymous method to System.Delegate mnMnu.BeginInvoke( new delegate(DIServer svr){ConfigureMainMenu(server);}, new object[] server); 

所以,简短的回答是否定的。 您可以在给定的上下文中创建简短的助手委托,并使用lambdas使其更整洁,但这就是它。

编辑:结果我错了。 下面的methodinvoker答案有效。 见本页