已经有两个很好的答案,但是要添加我的 0.02 ......
如果您正在谈论使用异步操作,那么async
/await
对 I/O 密集型和 CPU 密集型都非常有效。
我认为 MSDN 文档确实略微倾向于生成异步操作,在这种情况下,您确实希望将TaskCompletionSource
(或类似的)用于 I/O-bound 和Task.Run
(或类似的)用于 CPU-bound。创建初始Task
包装器后,最好由and使用它。async
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
}
使用ConfigureAwait
,如果 HTTP 请求没有立即(同步)完成,那么这将(在这种情况下)导致LoadHtmlDocument
在线程池线程上执行而无需显式调用Task.Run
.
如果您对async
这个级别的性能感兴趣,您应该查看 Stephen Toub 的视频和MSDN 文章关于该主题。他有大量有用的信息。