为什么我需要在所有的传递闭包中使用ConfigureAwait(false)?
为什么我需要在所有的传递闭包中使用ConfigureAwait(false)?
我正在学习async/await,并在阅读了这篇文章Don't Block on Async Code
以及这篇文章Is async/await suitable for methods that are both IO and CPU bound之后,我注意到了@Stephen Cleary的一条提示。
使用ConfigureAwait(false)来避免死锁是一种危险的做法。你必须在所有被阻塞代码调用的方法的传递闭包中使用ConfigureAwait(false),包括所有的第三方和第二方代码。使用ConfigureAwait(false)来避免死锁充其量只是一个hack)。
在上面附上的代码中,它再次出现了。
public async TaskLoadPage(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(false)时,其余的async方法将在线程池中运行。为什么我们需要在传递闭包中的每个await中添加它呢?我个人认为这是正确的版本,就像我所知道的那样。
public async TaskLoadPage(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()) //IO-bound return LoadHtmlDocument(contentStream); //CPU-bound }
这意味着在using块中的第二次使用ConfigureAwait(false)是无用的。请告诉我正确的方法。
提前感谢。