我刚刚在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的方式是什么,并且它的特殊之处在于代理必须被转换?
答案 0 :(得分:16)
我想向Svick指出更清晰的代码示例,毕竟我们都喜欢一个衬里不是吗?
Dispatcher.Invoke((Action) delegate { /* your method here */ });
答案 1 :(得分:10)
查看Dispatcher.Invoke()
的签名。它不需要Action
或其他特定的委托类型。它需要Delegate
,这是所有委托类型的共同祖先。但是您无法直接将匿名方法转换为此基本类型,您只能将其转换为某种特定的委托类型。 (这同样适用于lambda和方法组。)
为什么需要Delegate
?因为您可以传递带参数或具有返回值的委托。
最干净的方式可能是:
Action action = delegate()
{
// do stuff to UI
};
Dispatcher.Invoke(DispatcherPriority.Normal, action);
答案 2 :(得分:0)
'Delegate'类是abstract
,因此您必须为编译器提供从中派生的类型。从Delegate派生的任何类都可以,但Action通常是最合适的类。
答案 3 :(得分:0)
我用这个:
Dispatcher.Invoke((Action)(() => YourCodeHere()));