Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 正在检查线程是否为";“用户界面线程”;调用Dispatcher之前。调用冗余?_Wpf_Dispatcher_Ui Thread - Fatal编程技术网

Wpf 正在检查线程是否为";“用户界面线程”;调用Dispatcher之前。调用冗余?

Wpf 正在检查线程是否为";“用户界面线程”;调用Dispatcher之前。调用冗余?,wpf,dispatcher,ui-thread,Wpf,Dispatcher,Ui Thread,关于 Application.Current.Dispatcher.Invoke(action); 我已经研究了CheckAccess()和各种确定我是否在主UI线程上的方法。虽然在查看forInvoke之后,它似乎调用了CheckAccess(),并执行其他检查 调用源代码 public void Invoke(Action callback, DispatcherPriority priority, CancellationToken cancellationToken, TimeSpan

关于

Application.Current.Dispatcher.Invoke(action);
我已经研究了
CheckAccess()
和各种确定我是否在主UI线程上的方法。虽然在查看for
Invoke
之后,它似乎调用了
CheckAccess()
,并执行其他检查

调用源代码

public void Invoke(Action callback, DispatcherPriority priority, CancellationToken cancellationToken, TimeSpan timeout)
{
   ...
   ...

   // Fast-Path: if on the same thread, and invoking at Send priority,
   // and the cancellation token is not already canceled, then just
   // call the callback directly.
   if (!cancellationToken.IsCancellationRequested && priority == DispatcherPriority.Send && CheckAccess())
   {
      SynchronizationContext oldSynchronizationContext = SynchronizationContext.Current;

      try
      {
         DispatcherSynchronizationContext newSynchronizationContext;
         if (BaseCompatibilityPreferences.GetReuseDispatcherSynchronizationContextInstance())
         {
            newSynchronizationContext = _defaultDispatcherSynchronizationContext;
         }
         else
         {
            if (BaseCompatibilityPreferences.GetFlowDispatcherSynchronizationContextPriority())
            {
               newSynchronizationContext = new DispatcherSynchronizationContext(this, priority);
            }
            else
            {
               newSynchronizationContext = new DispatcherSynchronizationContext(this, DispatcherPriority.Normal);
            }
         }
         SynchronizationContext.SetSynchronizationContext(newSynchronizationContext);

         callback();
         ...
因此,检查是否需要调用我的对话框的最可靠方法是调用
Invoke
?当我无法访问
控件时,查看
检查访问
同步上下文
解决方案似乎是多余的

是这种情况,还是我遗漏了一些边缘案例,还是看不到隐藏的性能影响?

我想这取决于情况

如果您主要追求正确性和/或代码简洁性,那么是的,调用是冗余调用

Dispatcher.Invoke(action);
在功能上等同于1

然而,如果你关心的是性能,那么它就不那么明显了。逐字读

return Thread == Thread.CurrentThread;
因此,即使它被调用了两倍的次数,它也很难被注意到<代码>Dispatcher.Invoke
但是会做一些额外的工作,例如参数检查,可能还会交换同步上下文,因此我想它可能比对
CheckAccess()的冗余调用有更大的开销。但是,与性能优化一样,没有单一的正确答案——这取决于您的具体情况(例如,此代码从非UI线程调用的可能性)



1显然,在调用
Dispatcher.Invoke
时,同步上下文可能会发生其他事情,但是除非
action
正在使用它,否则结果将是相同的

特定的用例是,如果线程是UI,则它只是未知的,长话短说,它基本上是一个全局错误处理程序,用于通过对话框提醒用户的最后努力。不过,感谢您的详细回复
return Thread == Thread.CurrentThread;