gpt4 book ai didi

exception - async void、await 和异常 - 为什么 GUI 线程在 'await' 之后抛出的异常需要 AsyncVoidMethodBuilder 进行编码(marshal)?

转载 作者:行者123 更新时间:2023-12-02 23:59:08 24 4
gpt4 key购买 nike

在 C# 5.0 In A Nutshell,第 590 页中,给出了以下示例:

async void ButtonClick (object sender, RoutedEventArgs args) 
{
await Task.Delay(1000);
throw new Exception ("Will this be ignored?");
}

书上说异常不会被捕获,因为函数会在await行立即返回到消息循环,一秒后抛出异常时不会被消息中的try/catch捕获循环。

这本书接着指出,AsyncVoidMethodBuilder 必须将延续封装在另一个函数中,以便它可以构建另一个 try/catch block ,并将任何捕获的异常转发到同步上下文(如果存在)。

这让我感到困惑,因为我认为,由于 Task.Delay 是从 GUI 线程调用的,同步上下文的存在将导致 Task.Delay 的延续已经在 GUI 线程上执行。我本以为它可以直接从 try/catch 子句内的消息循环继续执行,并且仍然可以被捕获,而不需要封装在另一个函数中。

我错过了什么?

最佳答案

您的理解是正确的;该异常将直接在 UI SynchronizationContext 上重新引发,并由消息循环捕获。从那里它将传递到 UI 应用程序范围的处理程序。

这本书实际上说的是,async 方法返回后无法捕获异常,这就是为什么 AsyncVoidMethodBuilder 会在适当的位置重新引发异常。 SynchronizationContext

这很重要,因为 async void 方法可能会“离开”其 UI 上下文,例如,通过使用 ConfigureAwait(false)。但如果在此之后发生异常,则必须重新同步到原始 SynchronizationContext,而不一定是引发异常时的上下文。

关于exception - async void、await 和异常 - 为什么 GUI 线程在 'await' 之后抛出的异常需要 AsyncVoidMethodBuilder 进行编码(marshal)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21293656/

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