等待DownloadStringAsync与等待包装DownloadString的任务有什么区别?

时间:2017-01-08 23:25:32

标签: c# .net asynchronous async-await task

我理解WebClientDownloadStringAsync方法,可以像

一样使用
var result = await client.DownloadStringAsync(url); 

我想知道,只是在做什么

var result = await new Task<string>(() => client.DownloadString(url));

2 个答案:

答案 0 :(得分:5)

首先,您的第二个示例中有轻微的语法错误。您应该使用Task.Run代替:

var result = await Task<string>.Run(() => client.DownloadString(url));
  • 第一个示例在当前线程上启动DownloadStringAsync,然后释放该线程以执行其他工作。

  • 第二个示例创建一个新线程,然后在该线程上同步运行DownloadString

一个是否优于另一个取决于Task是否受CPU限制。在这种情况下,DownloadStringAsync更好,因为它不会消耗线程。

DownloadStringAsync触发网络请求,当它从网络收到请求已完成的中断时,如果收到结果,则会继续。这意味着在那个时候,没有线程正在积极地等待它。

在其他情况下,Task受CPU约束,它并没有真正产生影响(可能存在任何小的开销)

修改

正如@ paulo-morgado在他的回答中所说,当你说DownloadStringAsync时,我想你的意思是DownloadStringTaskAsync。前者不返回Task,因此不能与async / await一起使用。后者是可以等待的。

答案 1 :(得分:1)

WebClient类优先于任务和Task-based Asynchronous Pattern (TAP)

因此,预先存在的异步后缀方法使用Event-based Asynchronous Pattern (EAP),其中回复以事件的形式出现。

通过DownloadStringAsync method收到DownloadCompletedEvent的重播。

根据TAP建议,当发生这种情况时,TAP方法应加上后缀 TaskAsync

这就是WebClient类所发生的事情。

如果您希望async-await友好地使用DownloadString method,则应使用DownloadStringTaskAsync method