Run “async” method on a background thread

To fix your example specifically:

public void Activate()
{
    Task.Factory.StartNew(() =>
    {
        //executes in thread pool.
        return GetSomething(); // returns a Task.
    }) // returns a Task<Task>.
    .Unwrap() // "unwraps" the outer task, returning a proxy
              // for the inner one returned by GetSomething().
    .ContinueWith(task =>
    {
        // executes in UI thread.
        Prop = task.Result;
    }, TaskScheduler.FromCurrentSynchronizationContext());
}

This will work, but it’s old-school.

The modern way to run something on a background thread and dispatch back to UI thread is to use Task.Run(), async, and await:

async void Activate()
{
    Prop = await Task.Run(() => GetSomething());
}

Task.Run will start something in a thread pool thread. When you await something, it automatically comes back in on the execution context which started it. In this case, your UI thread.

You should generally never need to call Start(). Prefer async methods, Task.Run, and Task.Factory.StartNew — all of which start the tasks automatically. Continuations created with await or ContinueWith are also started automatically when their parent completes.

Leave a Comment