我正在完成如下任务。
var task = Task<string>.Factory.StartNew(() => longrunningmethod()
.ContinueWith(a =>
longrunningmethodcompleted((Task<string>)a,
TaskScheduler.FromCurrentSynchronizationContext())));
task.Wait();
我的任务将调用longrunning方法,完成后将调用完成的方法。
在我的长期运动方法中,我推迟Thread.Sleep(30000)
。当我使用Task.wait系统挂起并且它没有调用longrunningmethodcompleted方法时。如果我不使用Task.wait,一切都很顺利。
答案 0 :(得分:12)
我强烈怀疑您的上下文是UI上下文。
在这种情况下,您导致死锁,因为您告诉longrunningmethodcompleted
在当前SynchronizationContext
上执行。
然后,您通过调用Wait
来阻止该上下文。延续将永远不会完成,因为它需要在Wait
中阻止的线程上执行。
要解决此问题,您无法在该上下文中继续运行Wait
。我假设longrunningmethodcompleted
必须在UI线程上运行,因此解决方案是通过调用Wait
替换对ContinueWith
的调用:
var ui = TaskScheduler.FromCurrentSynchronizationContext();
var task = Task<string>.Factory.StartNew(() => longrunningmethod()
.ContinueWith(a =>
longrunningmethodcompleted((Task<string>)a,
ui);
task.ContinueWith(..., ui);
或者,您可以升级到VS2012并使用async
/ await
,这样可以编写更清晰的代码:
var task = Task.Run(() => longrunningmethod());
await task;
longrunningmethodcompleted(task);
答案 1 :(得分:0)
如果没有看到实际的异步操作是什么,很难说你的代码有什么问题,我所知道的只是根据MSDN waits for the task to be completed。是否有可能因为您尝试使用当前的SynchronizationContext操作阻止?
我问的原因是因为你
我的意思是你的程序与Thread.Sleep(seconds)
一起使用的原因是因为在时间限制结束后,线程将继续。
答案 2 :(得分:-1)
Thread.Sleep(nnn)正在阻止。使用Task.Delay(nnn)并等待:
await Task.Delay(30000);
编辑添加:刚刚注意到标签是C#4。这需要C#5和新的异步等待支持。说真的,如果你正在做异步和任务,你需要升级。