【发布时间】:2019-01-23 16:49:19
【问题描述】:
如果我有这样的电话:
Application.Current.Dispatcher.BeginInvoke(() => someAction);
从 Dispatcher 线程调用的它是排队等待稍后执行还是立即执行,因为它不需要从一个线程更改为另一个线程?
【问题讨论】:
标签: c# .net dispatcher begininvoke
如果我有这样的电话:
Application.Current.Dispatcher.BeginInvoke(() => someAction);
从 Dispatcher 线程调用的它是排队等待稍后执行还是立即执行,因为它不需要从一个线程更改为另一个线程?
【问题讨论】:
标签: c# .net dispatcher begininvoke
正如其他人指出的那样,它确实会排队。解决此问题的一个有用方法是定义:
public void DispatchIfNecessary(Action action) {
if (!Dispatcher.CheckAccess())
Dispatcher.Invoke(action);
else
action.Invoke();
}
可以这样称呼:
DispatchIfNecessary(() => {
someAction...
});
【讨论】:
它是排队等待稍后执行还是立即执行 因为它不需要从一个线程更改为另一个线程?
仍在排队。没有检查从哪个上下文调用该方法。可以看in the source:
private void InvokeAsyncImpl(DispatcherOperation operation,
CancellationToken cancellationToken)
{
DispatcherHooks hooks = null;
bool succeeded = false;
// Could be a non-dispatcher thread, lock to read
lock(_instanceLock)
{
if (!cancellationToken.IsCancellationRequested &&
!_hasShutdownFinished &&
!Environment.HasShutdownStarted)
{
// Add the operation to the work queue
operation._item = _queue.Enqueue(operation.Priority, operation);
// Make sure we will wake up to process this operation.
succeeded = RequestProcessing();
if (succeeded)
{
// Grab the hooks to use inside the lock; but we will
// call them below, outside of the lock.
hooks = _hooks;
}
else
{
// Dequeue the item since we failed to request
// processing for it. Note we will mark it aborted
// below.
_queue.RemoveItem(operation._item);
}
}
}
// Rest of method, shortened for brevity.
}
【讨论】:
在 Dispatcher 线程中运行代码并且所有其他排队的 BeginInvoke 完成执行后,它会排队等待执行
【讨论】: