3

我有以下扩展方法:

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

它基本上是一个同步方法调用包装器,用于返回一个字符串的异步方法调用。如果我逐行执行该代码,则代码可以正常工作,但是如果我让它自由执行,似乎会遇到一个不确定的块。有任何想法吗?

与我发布的上一个问题相关:如何更新我的 API 以使用 async 关键字而不为所有调用者使用 await

4

2 回答 2

10

正如一些人对您其他问题的答案所评论的那样,如果您Task.Result在 GUI 应用程序中使用,您可能会导致死锁(正如我在我的博客中详细解释的那样)。

简而言之:

  • 您在 UI 线程上启动异步操作。请注意,任务line代表ReadLineAsync方法,并且将在该方法完成时完成。
  • ReadLineAsync调用await一些不完整的操作。这会导致ReadLineAsync返回不完整的任务 ( line)。
  • 您阻塞了等待line完成的 UI 线程。
  • awaited 操作完成时,它将剩余的调度ReadLineAsync到 UI 线程。
  • UI 线程无法完成ReadLineAsync,因为它被同步阻塞等待ReadLineAsync完成。僵局。

有关解决此僵局的方法,请参阅我对您的其他问题的回答。简而言之:

  • ConfigureAwait(false)到处使用。
  • 更改您的错误处理以Result将其错误包含在AggregateException.
于 2013-01-07T02:30:09.707 回答
-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
}

也就是说,我还没有开始做这个异步业务。但是我已经阅读了文档等。

于 2013-04-27T06:07:04.097 回答