13

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

private void AddLog(string logItem)
        {

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

                    });
        }
4

2 回答 2

23

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

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

    Action action = delegate() { 
         this.Log.Add(...);
    };
    Dispatcher.BeginInvoke(action);
    
  2. 编写一个扩展方法,DispatcherAction不是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直接采用 a 的重载,因此在这种情况下您不需要扩展方法。

于 2013-04-10T20:39:15.507 回答
4

您也可以为此使用MethodInvoker :

private void AddLog(string logItem)
        {
            this.Dispatcher.BeginInvoke((MethodInvoker) delegate
            {
                this.Log.Add(new KeyValuePair<string, string>(DateTime.Now.ToLongTimeString(), logItem));
            });
        }
于 2015-09-09T15:03:40.270 回答