任务报告IsCompleted但仍然阻止结果?

时间:2012-02-16 09:57:52

标签: c# .net concurrency

我使用.Net 4类 System.Threading.Tasks 遇到了一些暴力行为。这个例子最好地证明了这一点:

var t = FunctionThatReturnsTaskAsync();
Trace.TraceInformation("Completed: " + t.IsCompleted);
return t.Result;

输出:“已完成:为真”,但代码(在几千次运行中一次)然后在t.Result永久阻止。它既不返回也不抛出异常。怎么会这样!

返回的任务有时很快完成,所以毫不奇怪它可以在第二行完成。这个谜团是t.Result阻止的原因。

1 个答案:

答案 0 :(得分:1)

异步方法本身返回任务,您可能有一个任务<任务< T> >由于'async',内部任务在“完成”之前返回,而外部任务<>认为它是完整的。

请参阅Stephen Toub的博客文章:

http://blogs.msdn.com/b/pfxteam/archive/2012/02/08/10265476.aspx

http://blogs.msdn.com/b/pfxteam/archive/2011/10/24/10229468.aspx

请允许我提出相关的引用:

  

要理解这种效果,我们需要记住异步方法的运作方式。当您调用异步方法时,它会同步开始运行。如果该方法没有任何等待,或者如果方法中的所有等待都在等待已经完成的等待时间,那么该方法将完全同步运行。但是,当方法遇到第一个等待yield时,async方法返回。对于返回Task或Task的异步方法,此时此方法返回表示异步方法执行的Task或Task,并且调用者可以使用该任务等待同步(例如Wait())或异步(例如await,ContinueWith)该方法异步完成。但是,在void方法的情况下,不会回交句柄。因此,异步空洞方法通常被称为“火与忘记”。