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(); } ```