gpt4 book ai didi

c# - async/await 是否适契约(Contract)时受 IO 和 CPU 限制的方法?

转载 作者:IT王子 更新时间:2023-10-29 03:57:25 24 4
gpt4 key购买 nike

MSDN 文档似乎指出 asyncawait 适用于 IO 绑定(bind)任务,而 Task.Run 应该用于 CPU -绑定(bind)任务。

我正在开发一个应用程序,该应用程序执行 HTTP 请求以检索 HTML 文档,然后对其进行解析。我有一个看起来像这样的方法:

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())
return await Task.Run(() => LoadHtmlDocument(contentStream)); //CPU-bound
}

asyncawait 是否适合使用,还是我过度使用了?

最佳答案

已经有两个很好的答案,但要加上我的 0.02...

如果您谈论的是消费异步操作,async/await 对于 I/O 绑定(bind)和 CPU 绑定(bind)都非常有效.

我认为 MSDN 文档确实对产生异步操作有轻微的倾向,在这种情况下,您确实希望对 I/O 使用 TaskCompletionSource(或类似的)- bound 和 Task.Run (或类似的)用于 CPU 绑定(bind)。一旦您创建了初始 Task 包装器,它最好由 asyncawait 使用

对于您的特定示例,它实际上归结为 LoadHtmlDocument 将花费多少时间。如果删除 Task.Run,您将在调用 LoadPage 的相同上下文中执行它(可能在 UI 线程上)。 Windows 8 指南规定,任何超过 50 毫秒的操作都应设为异步...请记住,在您的开发人员机器上,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 的 videoMSDN article 关于这个主题。他有大量有用的信息。

关于c# - async/await 是否适契约(Contract)时受 IO 和 CPU 限制的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14896856/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com