Yaw*_*aza 59 c# synchronizationcontext async-await
请考虑以下Windows窗体代码:
private async void UpdateUIControlClicked(object sender, EventArgs e)
{
this.txtUIControl.Text = "I will be updated after 2nd await - i hope!";
await Task.Delay(5000).ConfigureAwait(continueOnCapturedContext: false);
this.txtUIControl.Text = "I am updated now.";
}
Run Code Online (Sandbox Code Playgroud)
这里异常是在第3行引发的,因为在等待代码在非UI线程上执行之后.ConfigureAwait(false)有用吗?
小智 85
Stephen Cleary在这里有一个非常好的系列,你可以在这里找到,我引用了你的问题特定的部分:
大多数情况下,您不需要同步回"主"上下文.大多数异步方法都将在设计时考虑到组合:它们等待其他操作,每个操作本身代表一个异步操作(可以由其他操作组成).在这种情况下,您希望通过调用ConfigureAwait并传递来告知awaiter 不捕获当前上下文,例如:
falseRun Code Online (Sandbox Code Playgroud)private async Task DownloadFileAsync(string fileName) { // Use HttpClient or whatever to download the file contents. var fileContents = await DownloadFileContentsAsync(fileName).ConfigureAwait(false); // Note that because of the ConfigureAwait(false), we are not on the original context here. // Instead, we're running on the thread pool. // Write the file contents out to a disk file. await WriteToDiskAsync(fileName, fileContents).ConfigureAwait(false); // The second call to ConfigureAwait(false) is not *required*, but it is Good Practice. } // WinForms example (it works exactly the same for WPF). private async void DownloadFileButton_Click(object sender, EventArgs e) { // Since we asynchronously wait, the UI thread is not blocked by the file download. await DownloadFileAsync(fileNameTextBox.Text); // Since we resume on the UI context, we can directly access UI elements. resultTextBox.Text = "File downloaded!"; }这个例子需要注意的重要一点是,异步方法调用的每个"级别"都有自己的上下文.
DownloadFileButton_Click在UI上下文中启动,并调用DownloadFileAsync.DownloadFileAsync也是在UI上下文中开始,但后来通过调用走出了它的上下文ConfigureAwait(false).其余的DownloadFileAsync在线程池上下文中运行.但是,DownloadFileAsync完成并DownloadFileButton_Click恢复后,它会在UI上下文中恢复.一个好的经验法则是使用,
ConfigureAwait(false)除非你知道你确实需要上下文.
pix*_*xel 14
您应该始终在服务中使用它,因为服务应该与 UI 无关。
但是,如果出现以下情况,请不要在服务之外使用它
在这些情况下,您不应使用,ConfigureAwait(false)因为捕获当前上下文很重要,否则应用程序将因尝试从非 UI 线程访问 UI 视图而崩溃
当你写的时候await task;,这相当于写 await task.ConfigureAwait(true);。所以 true 是默认值。
| 归档时间: |
|
| 查看次数: |
40123 次 |
| 最近记录: |