匿名方法作为参数传递给BeginInvoke的?(Anonymous method as param

2019-06-23 11:17发布

为什么你不能传递一个匿名方法作为参数传递给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()

(能够做到这会适合整齐地用在哪些地方如此干净利落地工作在其他地方明确代表匿名方法/ 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
    }
}

Answer 1:

试试这个:

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

要么:

private void ConfigureMainMenu(DIServer server)
{
    if (control.InvokeRequired)
    {
        control.BeginInvoke(new Action<DIServer >(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 */
    }
}


Answer 2:

你应该能够写出这样的事情:

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


Answer 3:

你可以写,将包装匿名方法,甚至采取照顾的扩展方法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); });


Answer 4:

你可以通过调用调用自己在一个单独的方法做到这一点:

  ClassData updData =  new ClassData();

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

...

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


Answer 5:

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

Func<int, int?> caller = new Func<int, int?>((int param1) =>
   {
      return null;
   });

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

您可以使用其他函数功能的委托类型中的一种需要。



Answer 6:

我已经尝试了一堆不同的方法,但没有工作。 即...


// 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);

所以,简单的答案是否定的。 你可以在给定的环境中创建简短帮手代表和使用lambda表达式来使它有点整洁,但是这几乎是它。

编辑:原来我错了。 下面的methodinvoker答案的作品。 看到这个页面



文章来源: Anonymous method as parameter to BeginInvoke?