C# wpf 中的 InvokeRequired

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15504826/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 17:00:53  来源:igfitidea点击:

InvokeRequired in wpf

c#wpfwinformsinvokerequired

提问by oehgr

I used this function in a Windows formsapplication:

我在一个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();
}

But in WPFit doesn't work. Why?

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

回答by Servy

WPF uses the Dispatcherto control access to the message pump, rather than having each control be responsible for accessing the UI thread.

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

You should use Dispatcher.Invoketo add a delegate to the UI thread in a WPF application.

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

It's also worth noting that InvokeRequiredis not really needed in a winform app, nor is it something that you should be checking for in a WPF application. You should knowthat you're not in the UI thread when you call Invoke. You shouldn't ever be in a situation where a given method is sometimes called from the UI thread and sometimes called from a background thread. Choose one; either always force the caller to invoke to the UI thread before calling a given method (so you don't need to invoke) or assume that the caller won't be in the UI thread when the method is called. It's also worth noting that calling Invokewhen you're already in the UI thread is just fine. There are no errors or problems that will result from an occasional instance of re-invoking the UI thread (there's a very minor performance cost, so just don't add unneeded code for it all over the place).

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

回答by TalentTuner

回答by JaredPar

In WPF use the CheckAccessmethod instead of InvokeRequired

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

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

回答by Thomas Levesque

In WPF, the Invokemethod is on the dispatcher, so you need to call Dispatcher.Invokeinstead of Invoke. Also, there is no InvokeRequiredproperty, but the dispatcher has a CheckAccessmethod (for some reason, it's hidden in intellisense). So your code should be:

在 WPF 中,该Invoke方法在调度程序上,因此您需要调用Dispatcher.Invoke而不是Invoke. 此外,没有InvokeRequired属性,但调度程序有一个CheckAccess方法(出于某种原因,它隐藏在智能感知中)。所以你的代码应该是:

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