Task.wait和continueWIth

use*_*843 5 task-parallel-library c#-4.0

我正在完成如下任务.

var task = Task<string>.Factory.StartNew(() => longrunningmethod()
    .ContinueWith(a =>
             longrunningmethodcompleted((Task<string>)a,
                  TaskScheduler.FromCurrentSynchronizationContext())));

task.Wait();
Run Code Online (Sandbox Code Playgroud)

我的任务将调用longrunning方法,完成后将调用完成的方法.在我的长期运动方法中,我正在推迟Thread.Sleep(30000).当我使用Task.wait系统挂起并且它没有调用longrunningmethodcompleted方法时.如果我不使用Task.wait一切顺利.

Ste*_*ary 12

我强烈怀疑你的上下文是一个UI上下文.

在这种情况下,您正在导致死锁,因为您要告知longrunningmethodcompleted当前执行死锁SynchronizationContext.

然后你通过调用阻止该上下文Wait.延续将永远不会完成,因为它需要在被阻塞的线程上执行Wait.

要解决此问题,您不能Wait在该上下文中继续运行.我假设longrunningmethodcompleted 必须在UI线程上运行,因此解决方案是将调用替换WaitContinueWith:

var ui = TaskScheduler.FromCurrentSynchronizationContext();
var task = Task<string>.Factory.StartNew(() => longrunningmethod()
    .ContinueWith(a =>
         longrunningmethodcompleted((Task<string>)a,
         ui);
task.ContinueWith(..., ui);
Run Code Online (Sandbox Code Playgroud)

或者,您可以升级到VS2012并使用async/ await,这样可以编写更清晰的代码,如下所示:

var task = Task.Run(() => longrunningmethod());
await task;
longrunningmethodcompleted(task);
Run Code Online (Sandbox Code Playgroud)