我在Windows forms
应用程序中使用了此函数:
delegate void ParametrizedMethodInvoker5(int arg);
private void log_left_accs(int arg)
{
if (InvokeRequired)
{
Invoke(new ParametrizedMethodInvoker5(log_left_accs), arg);
return;
}
label2.Text = arg.ToString();
}
但是在WPF
它不起作用。为什么呢?
答案 0 :(得分:49)
在WPF中,Invoke
方法位于调度程序上,因此您需要调用Dispatcher.Invoke
而不是Invoke
。此外,没有InvokeRequired
属性,但调度程序具有CheckAccess
方法(出于某种原因,它隐藏在intellisense中)。所以你的代码应该是:
delegate void ParametrizedMethodInvoker5(int arg);
void log_left_accs(int arg)
{
if (!Dispatcher.CheckAccess()) // CheckAccess returns true if you're on the dispatcher thread
{
Dispatcher.Invoke(new ParametrizedMethodInvoker5(log_left_accs), arg);
return;
}
label2.Text= arg.ToString();
}
答案 1 :(得分:11)
在WPF中使用CheckAccess
方法而不是InvokeRequired
if (!CheckAccess()) {
// On a different thread
Dispatcher.Invoke(() => log_left_accs(arg));
return;
}
答案 2 :(得分:-1)
答案 3 :(得分:-2)
WPF使用Dispatcher
来控制对消息泵的访问,而不是让每个控件负责访问UI线程。
您应该使用Dispatcher.Invoke
将委托添加到WPF应用程序中的UI线程。
值得注意的是,在winform应用程序中并不真正需要InvokeRequired
,也不应该在WPF应用程序中检查它。当您致电Invoke
时,您应知道您不在UI线程中。您不应该处于有时从UI线程调用给定方法并且有时从后台线程调用的情况。选一个;要么总是强制调用者在调用给定方法之前调用UI线程(因此您不需要调用),或者假设调用该方法时调用者不在UI线程中。同样值得注意的是,当你已经在UI线程中时调用Invoke
就好了。偶尔重新调用UI线程的实例不会产生任何错误或问题(性能成本非常低,所以不要在整个地方添加不需要的代码)。