c#.net 4.5异步等待Task.Wait()阻塞问题

时间:2013-01-06 20:51:39

标签: c# .net deadlock .net-4.5 async-await

我有以下扩展方法:

internal static string ReadLine(this DataReader stream)
{
   Task<string> line = ReadLineAsync(stream);
   // line.Wait(); - Not Required, as next call blocks
   return line.Result;
}

它基本上是一个异步方法调用的同步方法调用包装器,它返回一个字符串。如果我逐行遍历它,代码工作正常,但似乎如果我让它自由执行,我会遇到一个无限期的块。有什么想法吗?

与我发布的上一个问题相关:How can I update my API to use the async keyword without using await for all callers

2 个答案:

答案 0 :(得分:8)

正如一些人对你的其他问题的回答发表评论,如果你在GUI应用程序中使用Task.Result,你可以cause a deadlock(正如我在我的博客中详细解释的那样)。

简而言之:

  • 您在UI线程上启动异步操作。请注意,任务line代表ReadLineAsync方法,并在该方法完成时完成。
  • ReadLineAsync对某些不完整的操作调用await。这会导致ReadLineAsync返回不完整的任务(line)。
  • 您阻止等待line完成的UI线程。
  • await ed操作完成时,它会将ReadLineAsync的剩余部分安排到UI线程。
  • UI线程无法完成ReadLineAsync,因为它会被同步阻止,等待ReadLineAsync完成。死锁。

请参阅my answer to your other question了解此死锁的方法。简而言之:

  • 到处使用ConfigureAwait(false)
  • 将您的错误处理更改为ResultAggregateException中包装错误的帐户。

答案 1 :(得分:-2)

根据:http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx 你不应该这样做:

internal static string ReadLine(this DataReader stream)
{
   string line = await ReadLineAsync(stream);
   return line
}

那就是说,我还没有开始这个Async业务。但我读过文件等等。