Run "async" method on a background thread

async-await, c#, windows-phone, windows-phone-7.1

Solution

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.

Problem

I'm trying to run an "async" method from an ordinary method: ``` public string Prop { get { return _prop; } set { _prop = value; RaisePropertyChanged(); } } private async Task<string> GetSomething() { return await new Task<string>( () => { Thread.Sleep(2000); return "hello world"; }); } public void Activate() { GetSomething.ContinueWith(task => Prop = task.Result).Start(); // ^ exception here } ``` The exception thrown is: Start may not be called on a continuation task. What does that mean, anyway? How can I simply run my async method on a background thread, dispatch the result back to the UI thread? Edit Also tried `Task.Wait`, but the waiting never ends: ``` public void Activate() { Task.Factory.StartNew<string>( () => { var task = GetSomething(); task.Wait(); // ^ stuck here return task.Result; }).ContinueWith(task => { Prop = task.Result; }, TaskScheduler.FromCurrentSynchronizationContext()); GetSomething.ContinueWith(task => Prop = task.Result).Start(); } ```

Original source