运行“异步"后台线程上的方法 [英] Run "async" method on a background thread
问题描述
我正在尝试从普通方法运行异步"方法:
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
}
抛出的异常是:
可能不会在继续任务上调用开始.
Start may not be called on a continuation task.
那到底是什么意思?如何简单地在后台线程上运行异步方法,然后将结果分配回UI线程?
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?
修改
还尝试了 Task.Wait
,但等待一直没有结束:
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();
}
推荐答案
要具体解决您的示例,
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.
在后台线程上运行某些东西并分派回UI线程的现代方法是使用 Task.Run()
, async
和 await
:
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
将在线程池线程中启动某些内容.当您 await
时,它会自动返回到启动它的执行上下文中.在这种情况下,您的UI线程.
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.
通常,您永远不需要调用 Start()
.首选 async
方法, Task.Run
和 Task.Factory.StartNew
-所有这些方法都会自动启动任务.当父项完成时,使用 await
或 ContinueWith
创建的继续也会自动开始.
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.
这篇关于运行“异步"后台线程上的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!