2013-01-06 53 views
1

我有以下的扩展方法:C#.NET 4.5的异步等待Task.Wait()阻塞问题

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

你究竟得到了什么?顺便说一句,你不需要呼叫line.Wait,呼叫line.Result是一个阻止呼叫,如果结果不可用 – MBen

+0

我改变了我的方法考虑到你的意见。该应用程序只是挂起,我没有看到我的输出或VS 2012中的本地窗口中的任何东西。 – c0D3l0g1c

+0

你是从UI线程运行这个吗? – dtb

回答

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)
  • 将错误处理更改为Result将错误包装在AggregateException中。
-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 
} 

这么说,我还没有开始这个异步业务。但是我读过文件等等。

+0

你不能在非'async'方法内使用'await' – W0lfw00ds

+0

是的 - 我现在知道了。我是一个noob然后:( –