我正在尝试从普通方法运行"异步"方法:
public string Prop { get { return _prop; } set { _prop = value; RaisePropertyChanged(); } } private async TaskGetSomething() { return await new Task ( () => { Thread.Sleep(2000); return "hello world"; }); } public void Activate() { GetSomething.ContinueWith(task => Prop = task.Result).Start(); // ^ exception here }
抛出的异常是:
可能不会在继续任务上调用Start.
无论如何,这是什么意思?如何在后台线程上运行异步方法,将结果发送回UI线程?
编辑
也尝试了Task.Wait
,但等待永远不会结束:
public void Activate() { Task.Factory.StartNew( () => { var task = GetSomething(); task.Wait(); // ^ stuck here return task.Result; }).ContinueWith(task => { Prop = task.Result; }, TaskScheduler.FromCurrentSynchronizationContext()); GetSomething.ContinueWith(task => Prop = task.Result).Start(); }
Cory Nelson.. 39
要具体修复您的示例:
public void Activate() { Task.Factory.StartNew(() => { //executes in thread pool. return GetSomething(); // returns a Task. }) // returns a 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()); }
这可行,但它是老派.
现代的方式运行在后台线程的东西,派遣回UI线程使用Task.Run()
,async
以及await
:
async void Activate() { Prop = await Task.Run(() => GetSomething()); }
Task.Run
将在线程池线程中启动一些东西.当你await
做某事时,它会自动回到启动它的执行上下文中.在这种情况下,您的UI线程.
你通常不需要打电话Start()
.首选async
方法,Task.Run
和Task.Factory.StartNew
- 所有方法都自动启动任务.使用await
或ContinueWith
在父项完成时自动启动的Continuations .
要具体修复您的示例:
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()); }
这可行,但它是老派.
现代的方式运行在后台线程的东西,派遣回UI线程使用Task.Run()
,async
以及await
:
async void Activate() { Prop = await Task.Run(() => GetSomething()); }
Task.Run
将在线程池线程中启动一些东西.当你await
做某事时,它会自动回到启动它的执行上下文中.在这种情况下,您的UI线程.
你通常不需要打电话Start()
.首选async
方法,Task.Run
和Task.Factory.StartNew
- 所有方法都自动启动任务.使用await
或ContinueWith
在父项完成时自动启动的Continuations .