Stephen Cleary对此有一个非常好的系列,您可以在这里找到,我引用了您的问题的特定文章:
大多数时候,您无需同步回“主要”上下文。大多数异步方法在设计时都会考虑到组合:它们等待其他操作,每个方法代表一个异步操作本身(可由其他人组成)。在这种情况下,您想通过调用ConfigureAwait并传递来告诉等待者不要捕获当前上下文,例如:false
private async Task DownloadFileAsync(string fileName)
{
var fileContents = await DownloadFileContentsAsync(fileName).ConfigureAwait(false);
await WriteToDiskAsync(fileName, fileContents).ConfigureAwait(false);
}
private async void DownloadFileButton_Click(object sender, EventArgs e)
{
await DownloadFileAsync(fileNameTextBox.Text);
resultTextBox.Text = "File downloaded!";
}
在此示例中要注意的重要一点是,异步方法调用的每个“级别”都有其自己的上下文。DownloadFileButton_Click
在UI上下文中启动,并称为DownloadFileAsync
。DownloadFileAsync
也从UI上下文开始,但随后通过调用退出其上下文ConfigureAwait(false)
。其余的DownloadFileAsync
运行在线程池上下文中。但是,DownloadFileAsync
完成并DownloadFileButton
_Click恢复时,它确实会在UI上下文中恢复。
ConfigureAwait(false)
除非您知道确实需要上下文,否则最好使用经验法则。