Search code examples
c#.netcompiler-errorsanonymous-methods

Anonymous method in Invoke call


Having a bit of trouble with the syntax where we want to call a delegate anonymously within a Control.Invoke.

We have tried a number of different approaches, all to no avail.

For example:

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

where someParameter is local to this method

The above will result in a compiler error:

Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type


Solution

  • Because Invoke/BeginInvoke accepts Delegate (rather than a typed delegate), you need to tell the compiler what type of delegate to create ; MethodInvoker (2.0) or Action (3.5) are common choices (note they have the same signature); like so:

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

    If you need to pass in parameters, then "captured variables" are the way:

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

    (caveat: you need to be a bit cautious if using captures async, but sync is fine - i.e. the above is fine)

    Another option is to write an extension method:

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

    then:

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

    You can of course do the same with BeginInvoke:

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

    If you can't use C# 3.0, you could do the same with a regular instance method, presumably in a Form base-class.