为什么异步方法不会立即返回等待?

时间:2014-08-21 13:13:27

标签: c# async-await

我原以为这是一个合理的模式,用于在事件处理程序中异步调用WebClient DownloadData:

private async void button1_Click(object sender, EventArgs e)
{
    WebClient wc = new WebClient();
    //wc.Proxy = null;
    byte[] bytes = await wc.DownloadDataTaskAsync("http://www.google.com");
    label1.Text = Encoding.ASCII.GetString(bytes);
}

但是在返回之前我发现DownloadDataTaskAsync块大约5秒钟(除非取消注释wc.Proxy = null语句)。如果一个方法可以随心所欲地执行非平凡的工作甚至在返回任务之前,那么该方法的意义何在?

大概这意味着安全我应该从不如上所述调用xAsync方法,而应该始终将它们包装在Task.Run()中以确保。或者不是?

2 个答案:

答案 0 :(得分:7)

这是WebClient / HttpWebRequest的已知问题:代理和DNS查找始终是同步完成的。这是一个错误,但微软已经决定不出于向后兼容性原因而修复它。

我建议的第一件事是使用HttpClient。如果这不起作用并且您需要异步,那么您可以将调用包裹在Task.Run中。

答案 1 :(得分:1)

事实证明,WebClient.DownloadDataTaskAsync正在调用HttpWebRequest.BeginGetResponse

MSDN指出:

  

BeginGetResponse方法需要一些同步设置任务   完成(DNS解析,代理检测和TCP套接字连接,   例如)此方法变为异步之前。 结果,   永远不应该在用户界面(UI)线程上调用此方法   因为它可能需要相当长的时间(最多几分钟)   根据网络设置)完成初始同步   在抛出错误的异常或方法之前设置任务   成功。

http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.begingetresponse(v=vs.110).aspx

不幸的是,MSDN documentation for WebClient.DownloadDataTaskAsync说:

  

此操作不会阻止。

似乎并非严格属实。

相关问题