无法将匿名方法转换为类型'System.Delegate',因为它不是委托类型

时间:2013-04-10 20:34:59

标签: c# wpf

我想在WPF应用程序的主线程上执行此代码并获取错误我无法弄清楚出了什么问题:

private void AddLog(string logItem)
        {

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

                    });
        }

2 个答案:

答案 0 :(得分:21)

匿名函数(lambda表达式和匿名方法)必须转换为特定的委托类型,而Dispatcher.BeginInvoke只需要Delegate。这有两种选择...

  1. 仍然使用现有的BeginInvoke调用,但请指定委托类型。这里有各种方法,但我通常会将匿名函数提取到以前的语句中:

    Action action = delegate() { 
         this.Log.Add(...);
    };
    Dispatcher.BeginInvoke(action);
    
  2. Dispatcher上写一个扩展方法,其中Action代替Delegate

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

    然后,您可以使用隐式转换

    调用扩展方法
    this.Dispatcher.BeginInvokeAction(
            delegate()
            {
                this.Log.Add(...);
            });
    
  3. 我还鼓励你通常使用lambda表达式而不是匿名方法:

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

    编辑:正如评论中所述,Dispatcher.BeginInvoke在.NET 4.5中获得了超载,直接使用Action,因此在这种情况下您不需要扩展方法。

答案 1 :(得分:3)

您也可以使用MethodInvoker

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