关于
Application.Current.Dispatcher.Invoke(action);
我查看了CheckAccess()
以及确定我是否在主UI线程上的各种方法。虽然在查看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
因此,检查是否需要调用对话框的最可靠方法是调用CheckAccess
?当我无法访问SynchronisationContexts
似乎是多余的时,查看Control
和return query.OrderByDescending(c=> c.Time.Ticks)
解决方案。
是这种情况还是有些边缘情况我不见了,或隐藏的性能打击我看不到?
答案 0 :(得分:2)
我想这取决于。
如果您主要是在正确性和/或代码简洁之后,那么是,呼叫是多余的 - 调用
Dispatcher.Invoke(action);
在功能上等同于 1 到
if(Dispatcher.CheckAccess())
action();
else
Dispatcher.Invoke(action);
如果你关心的是表现,那就不那么明显了。 CheckAccess
字面意思是
return Thread == Thread.CurrentThread;
因此,即使它被召唤两次,也几乎不会引起注意。 Dispatcher.Invoke
但是做了一些额外的工作,比如参数检查,可能还有交换同步上下文,所以我猜它可能比对CheckAccess()
的冗余调用有更大的开销。但是,与通常的性能优化一样,没有单一的正确答案 - 这取决于您的特定情况(例如,从非UI线程调用此代码的可能性)。
1显然,在调用 Dispatcher.Invoke
时,同步上下文可能会发生其他事情,但除非 action
正在使用它的结果将是相同的