调用WPF调度与匿名方法方法、WPF

2023-09-04 01:02:09 作者:趁年轻去努力、

我刚刚意识到在C#.NET 4.0 WPF后台线程,这不工作(编译错误):

I just realized in a C# .Net 4.0 WPF background thread that this doesn't work (compiler error):

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

这是一些例子,我发现,它已被铸造这样的:(行动)委托()。然而,在其它的实施例可以铸造其它类,例如 System.Windows.Forms.MethodInvoker

From some examples I found out that it had to be casted like this: (Action)delegate(). However, in other examples it is casted to other classes, e.g. System.Windows.Forms.MethodInvoker.

谁能告诉我到底什么是错与上面的例子?我也试过用其他方法复制它,但它始终工作而无需进行转换:

Can anybody tell me what exactly is wrong with the example above? I also tried to reproduce it with other methods, but it was always working without casting:

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();
}

所以,最新最好的(最优雅,少冗余)的方式来调用调度,和什么特别之处吧各位代表一定要铸造?

So whats the best (most elegant, less redundant) way to invoke the Dispatcher, and whats so special with it that delegates must be casted?

推荐答案

看签名 Dispatcher.Invoke() 。它并不需要动作或其他一些特定的委托类型。它采用代理,这是所有委托类型的共同祖先。但你不能转换匿名方法,以这个基类直接,你可以将其转换只是一些具体的委托类型。 (这同样适用于lambdas和方法团。)

Look at the signature for Dispatcher.Invoke(). It doesn't take Action or some other specific delegate type. It takes Delegate, which is the common ancestor of all delegate types. But you can't convert anonymous method to this base type directly, you can convert it only to some specific delegate type. (The same applies to lambdas and method groups.)

为什么要花代理?因为你可以传递给它的代表有参数或者返回值。

Why does it take Delegate? Because you can pass to it delegates that take parameters or have return values.

最彻底的方法可能是:

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

Dispatcher.Invoke(DispatcherPriority.Normal, action);