首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用ConfigureAwait(false)和Task.Run有什么区别?

使用ConfigureAwait(false)和Task.Run有什么区别?
EN

Stack Overflow用户
提问于 2013-02-16 09:49:04
回答 2查看 32.9K关注 0票数 58

我知道建议在库代码中对await使用ConfigureAwait(false),这样后续代码就不会在调用者的执行上下文中运行,而执行上下文可能是UI线程。出于同样的原因,我也理解应该使用await Task.Run(CpuBoundWork)而不是CpuBoundWork()

使用ConfigureAwait的示例

public async Task<HtmlDocument> LoadPage(Uri address)
{
    using (var client = new HttpClient())
    using (var httpResponse = await client.GetAsync(address).ConfigureAwait(false))
    using (var responseContent = httpResponse.Content)
    using (var contentStream = await responseContent.ReadAsStreamAsync().ConfigureAwait(false))
        return LoadHtmlDocument(contentStream); //CPU-bound
}

使用Task.Run的示例

public async Task<HtmlDocument> LoadPage(Uri address)
{
    using (var client = new HttpClient())
    using (var httpResponse = await client.GetAsync(address))
        return await Task.Run(async () =>
        {
            using (var responseContent = httpResponse.Content)
            using (var contentStream = await responseContent.ReadAsStreamAsync())
                return LoadHtmlDocument(contentStream); //CPU-bound
        });
}

这两种方法有什么不同?

EN

回答 2

Stack Overflow用户

发布于 2013-02-16 10:10:00

在这种情况下,您的Task.Run版本将有更多的开销,因为第一个等待调用(await client.GetAsync(address))仍将编组回调用上下文,Task.Run调用的结果也是如此。

另一方面,在第一个示例中,您的第一个Async()方法被配置为不需要封送回调用上下文,这使得context仍然可以在后台线程上运行。这样,就不会有任何编组回到调用者的上下文中。

票数 16
EN

Stack Overflow用户

发布于 2017-05-07 13:03:24

同意@Stephen回答,如果仍然困惑,请参阅下面的屏幕截图,不带ConfigureAwait的1# (False)

请参见下图尝试更新标签的主线程

带有ConfigureAwait的2# (False)

如下图所示,工作线程正在尝试更新标签

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14906092

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档