如果从同一个线程调用,Dispatcher.BeginInvoke 是否会将调用排队?
Does Dispatcher.BeginInvoke queues the call if it is called from the same thread?
如果我有这样的电话:
Application.Current.Dispatcher.BeginInvoke(() => someAction);
从 Dispatcher 线程调用的它是排队等待稍后执行还是立即执行,因为它不需要从一个线程切换到另一个线程?
在 Dispatcher 线程中的 运行 代码和所有其他排队的 BeginInvoke 完成执行后
,它会排队等待执行
does it get queued to be executed later or gets it executed instantly
as it does not need to change from one thread to another one?
还在排队。不检查调用该方法的上下文。可以看到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.
}
正如其他人指出的那样,它确实需要排队。解决这个问题的一个有用方法是定义:
public void DispatchIfNecessary(Action action) {
if (!Dispatcher.CheckAccess())
Dispatcher.Invoke(action);
else
action.Invoke();
}
可以这样称呼:
DispatchIfNecessary(() => {
someAction...
});
如果我有这样的电话:
Application.Current.Dispatcher.BeginInvoke(() => someAction);
从 Dispatcher 线程调用的它是排队等待稍后执行还是立即执行,因为它不需要从一个线程切换到另一个线程?
在 Dispatcher 线程中的 运行 代码和所有其他排队的 BeginInvoke 完成执行后
,它会排队等待执行does it get queued to be executed later or gets it executed instantly as it does not need to change from one thread to another one?
还在排队。不检查调用该方法的上下文。可以看到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.
}
正如其他人指出的那样,它确实需要排队。解决这个问题的一个有用方法是定义:
public void DispatchIfNecessary(Action action) {
if (!Dispatcher.CheckAccess())
Dispatcher.Invoke(action);
else
action.Invoke();
}
可以这样称呼:
DispatchIfNecessary(() => {
someAction...
});