2013-04-10 85 views
8

我想执行在WPF应用程序主线程和得到错误的代码我无法弄清楚什么是错的:无法转换匿名法键入“System.Delegate”,因为它不是一个委托类型

private void AddLog(string logItem) 
     { 

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

        }); 
     } 
+1

采取这里看看http://stackoverflow.com/questions/4936459/dispatcher-begininvoke-cannot-convert-lambda-to-system-delegate – MethodMan 2013-04-10 20:38:01

回答

20

匿名函数(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(...); 
         }); 
    

我还鼓励您使用lambda表达式,而不是匿名方法,一般来说:

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

编辑:正如在评论中指出,Dispatcher.BeginInvoke获得了.NET 4.5超载直接接受一个Action,所以在这种情况下,你不需要扩展方法。

+0

我遇到了同样的问题,然后发现4.5版.NET中的Dispatcher类有重载(例如:http://msdn.microsoft.com/en-us/library/hh199416(v=vs.110) ).aspx)接受一个Action委托,所以代码没有显式的委托类型规范。 – 2014-07-23 09:12:14

+0

@Mark:很好 - 会编辑。 – 2014-07-23 09:15:11

2

您还可以使用MethodInvoker此:

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