gpt4 book ai didi

c# - 在 C# 5 中将 WPF 事件处理程序声明为 'async' 的意义

转载 作者:IT王子 更新时间:2023-10-29 04:48:32 26 4
gpt4 key购买 nike

想象一个 WPF 代码隐藏事件处理程序:

<Button Click="OnButtonClick" />

在 C# 4 中,您可以将处理程序声明为:

private void OnButtonClick(object sender, RoutedEventArgs e) { ... }

在 C# 5 中,您可以声明一个 async 处理程序

private async void OnButtonClick(object sender, RoutedEventArgs e) { ... }

那么 WPF 用这个做什么呢?搜索了几分钟没有找到任何结果。

似乎可以在 await 语句之后执行 UI 更新。这是否意味着任务在 Dispatcher 线程上继续?

如果 Task 引发错误,它会通过 WPF Dispatcher 引发,还是仅通过 TaskScheduler 引发?

还有其他有趣的方面可能很容易理解吗?

最佳答案

你可以找到我的 async/await intro有帮助。

async 方法由编译器重写以支持 await 运算符。每个 async 方法开始时都是同步的(在本例中,在 UI 线程上),直到它 await 一些操作(尚未完成)。

默认情况下,上下文会被保存,当操作完成时,方法的其余部分会安排在该上下文中执行。这里的“上下文”是 SynchronizationContext.Current 除非它是 null,在这种情况下它是 TaskScheduler.Current。正如 Drew 所指出的,WPF 提供了一个 DispatcherSynchronizationContext,它与 WPF Dispatcher 相关联。

关于错误处理:

当您在 WPF async void 事件处理程序中await Task 时,错误处理如下:

  • 任务 完成但出现错误。异常被包装到 AggregateException 中,就像所有 Task 错误一样。
  • await 运算符发现 Task 已完成但出现错误。它解包原始异常并重新抛出它,保留原始堆栈跟踪。
  • async void 方法构建器捕获从 async void 方法转义的异常,并将其传递给 SynchronizationContextSynchronizationContextasync void 方法开始执行(在本例中,相同的 WPF 上下文)。
  • Dispatcher 上引发异常(使用原始堆栈跟踪,并且没有任何恼人的 AggregateException 包装)。

这相当复杂,但目的是让 async 事件处理程序引发的异常实际上与常规事件处理程序引发的异常相同。

关于c# - 在 C# 5 中将 WPF 事件处理程序声明为 'async' 的意义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12556993/

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