Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Anonymous method as parameter to BeginInvoke?

Why can't you pass an anonymous method as a parameter to the BeginInvoke method? I have the following code:

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
    }
}

I'm trying to avoid declaring the delegate. Why can't I write something like the below instead? Or can I, and I just can't figure out the correct syntax? The below currently generates an:

Argument type 'Anonymous method' is not assignable to parameter type 'System.Delegate'

Ok, that's right of course, but is there some other syntax I can use to do this (avoid having to declare a separate delegate in order to use BeginInvoke()?

(Being able to do this would fit in neatly with the concept of using anon methods/lamdas in place of explicit delegates which works so cleanly everywhere else.)

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
    }
}
like image 488
Charles Bretana Avatar asked Jun 17 '09 14:06

Charles Bretana


4 Answers

Try this:

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

Or:

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

Or:

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 */
    }
}
like image 163
ilitirit Avatar answered Nov 11 '22 16:11

ilitirit


You should be able to write something like this:

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
    }
}
like image 37
Jake Avatar answered Nov 11 '22 17:11

Jake


You could write an extension method that would wrap anonymous methods, and even take care of the InvokeRequired semantics:

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

This would allow you to do:

control.InvokeAction(delegate() { ConfigureMainMenu(server); });
like image 28
Jason Avatar answered Nov 11 '22 16:11

Jason


You can do this in a single method by calling invoking yourself:

  ClassData updData =  new ClassData();

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

...

public void FillCurve(ClassData updData)
{
 ...
}
like image 1
RckLN Avatar answered Nov 11 '22 15:11

RckLN