Ignacio Soler Garcia
Ignacio Soler Garcia

Reputation: 21855

Does Dispatcher.BeginInvoke queues the call if it is called from the same thread?

If I have a call like:

Application.Current.Dispatcher.BeginInvoke(() => someAction);

that is called from the Dispatcher thread 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?

Upvotes: 2

Views: 807

Answers (3)

Ricibob
Ricibob

Reputation: 7725

As others have pointed out it does get queued yes. A useful way to get around this is to define:

public void DispatchIfNecessary(Action action) {
    if (!Dispatcher.CheckAccess())
        Dispatcher.Invoke(action);
    else
        action.Invoke();
}

Which can be called as:

DispatchIfNecessary(() => {
    someAction...
});

Upvotes: 3

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149608

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?

Still gets queued. There is no checking of which context the method was called from. You can see it 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.
}

Upvotes: 2

Denis  Yarkovoy
Denis Yarkovoy

Reputation: 1307

It gets queued to be executed after your running code in the Dispatcher thread and all other queued BeginInvoke's finish executing

Upvotes: 1

Related Questions