使用匿名方法调用WPF Dispatcher

Han*_*obo 9 .net c# wpf delegates dispatcher

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

Dispatcher.Invoke(DispatcherPriority.Normal, delegate()
{
    // do stuff to UI
});
Run Code Online (Sandbox Code Playgroud)

从一些例子中我发现它必须像这样铸造:(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();
}
Run Code Online (Sandbox Code Playgroud)

那么最好的(最优雅的,更少冗余的)调用Dispatcher的方式是什么,并且它的特殊之处在于代理必须被转换?

Jas*_*ska 18

我想向Svick的一个更清晰的代码示例指出,毕竟我们都喜欢一个衬里不是吗?

Dispatcher.Invoke((Action) delegate { /* your method here */ });
Run Code Online (Sandbox Code Playgroud)

  • +1 - 我部分不同意Servy.Jaska,请编辑你的答案,以便自信地说:这是涉及匿名方法的最简洁方法.您的答案正是回答问题标题:"使用匿名方法调用WPF Dispatcher". - 谢谢,你呢. (3认同)

svi*_*ick 10

看看签名Dispatcher.Invoke().它不需要Action或其他特定的委托类型.它需要Delegate,这是所有委托类型的共同祖先.但是您无法直接将匿名方法转换为此基本类型,您只能将其转换为某种特定的委托类型.(这同样适用于lambdas和方法组.)

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

最干净的方式可能是:

Action action = delegate()
{
    // do stuff to UI
};

Dispatcher.Invoke(DispatcherPriority.Normal, action);
Run Code Online (Sandbox Code Playgroud)