Coder Perfect

UI thread for task continuation


Is there a’standard’ way to tell a task continuation that it should execute on the same thread as the original task?

I now have the code below, which works, but I don’t think maintaining track of the dispatcher and creating a second Action is essential.

dispatcher = Dispatcher.CurrentDispatcher;
Task task = Task.Factory.StartNew(() =>

Task UITask= task.ContinueWith(() =>
    dispatcher.Invoke(new Action(() =>
        this.TextBlock1.Text = "Complete"; 

Asked by Greg Sansom

Solution #1

TaskScheduler is used to call the continuation. FromCurrentSynchronizationContext():

    Task UITask= task.ContinueWith(() =>
     this.TextBlock1.Text = "Complete"; 
    }, TaskScheduler.FromCurrentSynchronizationContext());

Only if the current execution context is on the UI thread is this appropriate.

Answered by Greg Sansom

Solution #2

With async, all you have to do is:

await Task.Run(() => do some stuff);
// continue doing stuff on the same context as before.
// while it is the default it is nice to be explicit about it with:
await Task.Run(() => do some stuff).ConfigureAwait(true);


await Task.Run(() => do some stuff).ConfigureAwait(false);
// continue doing stuff on the same thread as the task finished on.

Answered by Johan Larsson

Solution #3

If you need to transmit a return value to the user interface, you can use the generic version, which looks like this:

In my example, this is being called from an MVVM ViewModel.

var updateManifest = Task<ShippingManifest>.Run(() =>
        Thread.Sleep(5000);  // prove it's really working!

        // GenerateManifest calls service and returns 'ShippingManifest' object 
        return GenerateManifest();  

    .ContinueWith(manifest =>
        // MVVM property
        this.ShippingManifest = manifest.Result;

        // or if you are not using MVVM...
        // txtShippingManifest.Text = manifest.Result.ToString();    

        System.Diagnostics.Debug.WriteLine("UI manifest updated - " + DateTime.Now);

    }, TaskScheduler.FromCurrentSynchronizationContext());

Answered by Simon_Weaver

Solution #4

I just wanted to add this version because I think it’s a pretty simple implementation and this is such a great discussion. I’ve used this in a variety of multithreaded applications, including:

 Task.Factory.StartNew(() =>
        Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
              { txt.Text = "Complete"; }));

Answered by Dean

Solution #5

I found this site via Google when looking for a nice way to conduct stuff on the ui thread after being inside a Task. Run call – You may use await to return to the UI Thread using the following code.

I hope this information is useful to someone.

public static class UI
    public static DispatcherAwaiter Thread => new DispatcherAwaiter();

public struct DispatcherAwaiter : INotifyCompletion
    public bool IsCompleted => Application.Current.Dispatcher.CheckAccess();

    public void OnCompleted(Action continuation) => Application.Current.Dispatcher.Invoke(continuation);

    public void GetResult() { }

    public DispatcherAwaiter GetAwaiter()
        return this;


... code which is executed on the background thread...
await UI.Thread;
... code which will be run in the application dispatcher (ui thread) ...

Answered by Dbl

Post is based on