【问题标题】:Invoking WPF Dispatcher with anonymous method使用匿名方法调用 WPF Dispatcher
【发布时间】:2011-06-05 20:45:04
【问题描述】:

我刚刚在 C# .Net 4.0 WPF 后台线程中意识到这不起作用(编译器错误):

Dispatcher.Invoke(DispatcherPriority.Normal, delegate()
{
    // do stuff to UI
});

从一些示例中我发现它必须像这样转换:(Action)delegate()。但是,在其他示例中,它被强制转换为其他类,例如System.Windows.Forms.MethodInvoker.

谁能告诉我上面的例子到底有什么问题?我也尝试用其他方法重现它,但它总是在没有强制转换的情况下工作:

delegate void MyAction();
void Method1(MyAction a) {
    // do stuff
}

void Method2(Action a) {
    // do stuff
}

void Tests()
{
    Method1(delegate()
    {
        // works
    });

    Method2(delegate()
    {
        // works
    });

    Method1(() =>
    { 
        // works
    });

    Method2(() =>
    {
        // works
    });

    Method2(new Action(delegate()
    {
        // works
    }));

    new System.Threading.Thread(delegate()
    {
        // works
    }).Start();
}

那么调用 Dispatcher 的最佳(最优雅、更少冗余)的方式是什么,它有什么特别之处以至于必须强制转换委托?

【问题讨论】:

    标签: c# .net wpf delegates dispatcher


    【解决方案1】:

    我想指出 Svick 的更简洁的代码示例,毕竟我们都喜欢一个班轮,不是吗?

    Dispatcher.Invoke((Action) delegate { /* your method here */ });
    

    【讨论】:

    • 这真的是评论,而不是答案。它缺乏问题所要求的所有解释。
    • Servy:是的,我完全错过了问这个问题的人实际上回答了他自己的问题的那句话。对不起:(
    • +1 - 我部分不同意Servy。 Jaska,请编辑您的答案,以便自信地说:这是涉及匿名方法的最干净的方式。您的答案正是在回答问题标题:“Invoking WPF Dispatcher with anonymous method”。 - 谢谢你。
    【解决方案2】:

    查看Dispatcher.Invoke() 的签名。它不需要Action 或其他一些特定的委托类型。它需要Delegate,它是所有委托类型的共同祖先。但是你不能直接将匿名方法转换为这个基类型,你只能将它转换为一些特定的委托类型。 (同样适用于 lambda 和方法组。)

    为什么需要Delegate?因为您可以将带参数或具有返回值的委托传递给它。

    最干净的方法可能是:

    Action action = delegate()
    {
        // do stuff to UI
    };
    
    Dispatcher.Invoke(DispatcherPriority.Normal, action);
    

    【讨论】:

    • 您可以使用方法组,例如动作动作 = MyMethod;
    【解决方案3】:

    我用这个:

    Dispatcher.Invoke((Action)(() => YourCodeHere()));

    【讨论】:

      【解决方案4】:

      “Delegate”类是abstract,因此您必须为编译器提供一个派生自它的类型。任何派生自 Delegate 的类都可以,但 Action 通常是最合适的。

      【讨论】:

      • 是的,但是delegate {} 看起来 已经是从Delegate 派生的类型,所以你的回答没有解释为什么需要强制转换。
      • delegate(小写)是一个 c# 关键字,而不是一个类。这是一个非常常见的混淆。
      • @Robert,我不是在谈论某种类型 delagate(你说得对,这种类型不存在),我在谈论表达式 delegate { },它声明了一个匿名方法,因此认为表达式可以隐式转换为Delegate 是有意义的。
      • @svick 是的,但是编译器推断的问题是您的方法应该是什么 type 委托。它不能是 Delegate 类型,因为那是抽象的。编译器可能会被赋予一些智能来根据您的参数和返回类型(如果有)创建一个匿名的 Delegate 子类,然后代表您强制转换......但从.NET 4开始,他们还没有这样做.也许下次?
      • @Robert,是的,这就是我的观点,我认为这从你的回答中并不明显。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-27
      • 1970-01-01
      • 2010-09-20
      • 1970-01-01
      相关资源
      最近更新 更多