Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

wpf

I want to execute this code on main thread in WPF app and getting error I can't figure out what is wrong:

private void AddLog(string logItem)
        {

            this.Dispatcher.BeginInvoke(
                delegate()
                    {
                        this.Log.Add(new KeyValuePair<string, string>(DateTime.Now.ToLongTimeString(), logItem));

                    });
        }
like image 392
katit Avatar asked Apr 10 '13 20:04

katit


2 Answers

You can also use MethodInvoker for this:

private void AddLog(string logItem)
        {
            this.Dispatcher.BeginInvoke((MethodInvoker) delegate
            {
                this.Log.Add(new KeyValuePair<string, string>(DateTime.Now.ToLongTimeString(), logItem));
            });
        }
like image 128
Pinetwig Avatar answered Oct 19 '22 12:10

Pinetwig


Anonymous functions (lambda expressions and anonymous methods) have to be converted to a specific delegate type, whereas Dispatcher.BeginInvoke just takes Delegate. There are two options for this...

  1. Still use the existing BeginInvoke call, but specify the delegate type. There are various approaches here, but I generally extract the anonymous function to a previous statement:

    Action action = delegate() { 
         this.Log.Add(...);
    };
    Dispatcher.BeginInvoke(action);
    
  2. Write an extension method on Dispatcher which takes Action instead of Delegate:

    public static void BeginInvokeAction(this Dispatcher dispatcher,
                                         Action action) 
    {
        Dispatcher.BeginInvoke(action);
    }
    

    Then you can call the extension method with the implicit conversion

    this.Dispatcher.BeginInvokeAction(
            delegate()
            {
                this.Log.Add(...);
            });
    

I'd also encourage you to use lambda expressions instead of anonymous methods, in general:

Dispatcher.BeginInvokeAction(() => this.Log.Add(...));

EDIT: As noted in comments, Dispatcher.BeginInvoke gained an overload in .NET 4.5 which takes an Action directly, so you don't need the extension method in that case.

like image 23
Jon Skeet Avatar answered Oct 19 '22 10:10

Jon Skeet