已经有两个很好的答案了,但要加上我的 0.02...
如果你说的是消耗异步操作,async
/await
非常适合 I/O 密集型和 CPU 密集型。
我认为 MSDN 文档确实有轻微的倾向生产异步操作,在这种情况下你确实想使用TaskCompletionSource
(或类似)用于 I/O 绑定和Task.Run
(或类似)用于 CPU 限制。一旦你创建了初始的Task
包装,最好consumed by async
and await
.
对于您的特定示例,这实际上取决于多少时间LoadHtmlDocument
会采取。如果您删除Task.Run
,您将在调用的同一上下文中执行它LoadPage
(可能在 UI 线程上)。 Windows 8 指南规定任何耗时超过 50 毫秒的操作都应执行async
...请记住,开发人员计算机上的 50 毫秒可能在客户端计算机上更长...
所以如果你能保证LoadHtmlDocument
运行时间不到50ms,直接执行即可:
public async Task<HtmlDocument> LoadPage(Uri address)
{
using (var httpResponse = await new HttpClient().GetAsync(address)) //IO-bound
using (var responseContent = httpResponse.Content)
using (var contentStream = await responseContent.ReadAsStreamAsync()) //IO-bound
return LoadHtmlDocument(contentStream); //CPU-bound
}
不过,我会推荐ConfigureAwait
正如@svick提到的:
public async Task<HtmlDocument> LoadPage(Uri address)
{
using (var httpResponse = await new HttpClient().GetAsync(address)
.ConfigureAwait(continueOnCapturedContext: false)) //IO-bound
using (var responseContent = httpResponse.Content)
using (var contentStream = await responseContent.ReadAsStreamAsync()
.ConfigureAwait(continueOnCapturedContext: false)) //IO-bound
return LoadHtmlDocument(contentStream); //CPU-bound
}
With ConfigureAwait
,如果 HTTP 请求没有立即(同步)完成,那么这将(在这种情况下)导致LoadHtmlDocument
在线程池线程上执行,无需显式调用Task.Run
.
如果您有兴趣async
在这个级别的表现,你应该看看 Stephen Toub 的video http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-829T and MSDN 文章 http://msdn.microsoft.com/en-us/magazine/hh456402.aspx就此主题而言。他有大量有用的信息。