Task.wait和continueWIth [英] Task.wait and continueWIth
问题描述
var task = Task< string> .Factory.StartNew(()= > longrunningmethod()
.ContinueWith(a =>
longrunningmethodcompleted((Task< string>)a,
TaskScheduler.FromCurrentSynchronizationContext()))))
task.Wait();
我的任务将调用longrunning方法,完成后将调用completed方法。
在我的longrunning方法我延迟 Thread.Sleep(30000)
。当我使用Task.wait系统挂起,它不调用longrunningmethodcompleted方法。如果我不使用Task.wait,一切都很好。
我强烈怀疑你的上下文是一个UI上下文。 p>
在这种情况下,你会导致死锁,因为你告诉 longrunningmethodcompleted
在当前 SynchronizationContext
。
然后你通过调用 Wait
中。继续将永远不会完成,因为它需要在 Wait
中阻塞的线程上执行。
修复此问题,则不能对在该上下文中运行的延续使用 Wait
。我假设 longrunningmethodcompleted
必须在UI线程上运行,所以解决方案是替换调用 Wait
调用 ContinueWith
:
var ui = TaskScheduler.FromCurrentSynchronizationContext();
var task = Task> .Factory.StartNew(()=> longrunningmethod()
.ContinueWith(a =>
longrunningmethodcompleted((Task< string>)a,
ui);
task.ContinueWith(...,ui);
或者,您可以升级到VS2012并使用 async
/ await
,这样可以编写更清晰的代码, / p>
var task = Task.Run(()=> longrunningmethod());
await task;
longrunningmethodcompleted(task);
I am having a task like below.
var task = Task<string>.Factory.StartNew(() => longrunningmethod()
.ContinueWith(a =>
longrunningmethodcompleted((Task<string>)a,
TaskScheduler.FromCurrentSynchronizationContext())));
task.Wait();
My task will call the longrunningmethod and after completing it will call completed method.
Inside my longrunningmethod I am delaying by Thread.Sleep(30000)
. When I use Task.wait system hangs and it's not calling longrunningmethodcompleted method. If I don't use Task.wait everything flows good.
I strongly suspect your context is a UI context.
In that case, you're causing the deadlock because you're telling longrunningmethodcompleted
to execute on the current SynchronizationContext
.
Then you're blocking that context by calling Wait
. The continuation will never complete because it needs to execute on the thread that is blocked in Wait
.
To fix this, you can't use Wait
on a continuation running in that context. I'm assuming that longrunningmethodcompleted
must run on the UI thread, so the solution is to replace the call to Wait
with a call to ContinueWith
:
var ui = TaskScheduler.FromCurrentSynchronizationContext();
var task = Task<string>.Factory.StartNew(() => longrunningmethod()
.ContinueWith(a =>
longrunningmethodcompleted((Task<string>)a,
ui);
task.ContinueWith(..., ui);
Or, you can upgrade to VS2012 and use async
/await
, which lets you write much cleaner code like this:
var task = Task.Run(() => longrunningmethod());
await task;
longrunningmethodcompleted(task);
这篇关于Task.wait和continueWIth的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!