在wpf中调用InvokeRequired

oeh*_*hgr 31 c# wpf invokerequired winforms

我在一个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();
}
Run Code Online (Sandbox Code Playgroud)

但在WPF它不起作用.为什么?

Tho*_*que 53

在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();
}
Run Code Online (Sandbox Code Playgroud)

  • Dispatcher的值可能为null。这就是为什么DispatcherObject具有CheckAccess方法的原因,它说明了这种可能性 (2认同)
  • 我相信当一个对象被冻结时,它的“Dispatcher”将为“null”。查找对“DispatherObject.DetachFromDispatcher”的引用 (2认同)

Jar*_*Par 14

在WPF中使用该CheckAccess方法而不是InvokeRequired

if (!CheckAccess()) { 
  // On a different thread
  Dispatcher.Invoke(() => log_left_accs(arg));
  return;
}
Run Code Online (Sandbox Code Playgroud)


Ser*_*rvy -1

WPF 使用 来Dispatcher控制对消息泵的访问,而不是让每个控件负责访问 UI 线程。

您应该使用Dispatcher.Invoke向 WPF 应用程序中的 UI 线程添加委托。

还值得注意的是,这InvokeRequired在 winform 应用程序中并不是真正需要的,也不应该在 WPF 应用程序中检查。您应该知道,当您调用 时,您并不在 UI 线程中Invoke。您不应该遇到这样的情况:给定方法有时从 UI 线程调用,有时从后台线程调用。选一个; 要么始终强制调用者在调用给定方法之前调用 UI 线程(因此您不需要调用),要么假设调用该方法时调用者不会位于 UI 线程中。还值得注意的是,Invoke当您已经处于 UI 线程中时进行调用就可以了。偶尔重新调用 UI 线程不会导致错误或问题(性能成本非常小,因此不要到处添加不需要的代码)。

  • 当然,在很多情况下,您不知道自己是否在创建线程上,而必须检查它! (6认同)