C# async await (try/)catch 在 .NET 6 中失败

C# async await (try/)catch fails in .NET 6

以下代码在(.NET 4.8 项目的 WPF UserControl 的代码隐藏中按预期工作。

    private async Task DeleteAsync()
    {
        try
        {
            await ViewModel.DeleteAsync(GetSelectedItems());
        }
        catch (Exception ex)
        {
            var doCatch = ex is ValidationException
                || ex is ExpectedInfoException
                || ex is ExpectedDbException;
            if (doCatch)
                ExeptionHelper.HandleException(ex, AppConstants.ApplicationName);
            else
                throw;
        }
    }

以下模拟实验并不总是在 .NET 6.0 项目中捕获异常,请参阅内联注释。 我对最小可重现复制样本的尝试还没有完成,但希望有人已经对原因有了有根据的猜测?

        private async void DeleteListAsync()
        {
            var list = ViewModel.GetSelectedItems(
                dataGrid.SelectedItems.OfType<ActorModel>().ToList());
            try
            {
                await ViewModel.DeleteListAsync(list);
            }
            catch (Exception ex) when (
                ex is ValidationException
                || ex is ExpectedInfoException
                || ex is ExpectedDbException)
            {
                /* this part does run as expected when() one of those three 
                 * custom MyNamespace.Exceptions gets thrown in the previous `try` block.
                 * But unexpectedly *not when thrown inside the nested step-into code of 
                 * ViewModel.DeleteListAsync() */
                ApplicationHelper.HandleException(ex, Intl.LocalizedConstants.AppName);
            }
            catch
            {
                /* this part does run as expected when a `new InvalidOperationException("Test")`
                 * or `NotImplementedException()` gets thrown directly in the `try`block.
                 * Also when thrown inside the nested step-into code of 
                 * ViewModel.DeleteListAsync() */
                throw;
            }
        }

[已解决]: 很久以后,在有用的注释的帮助下,我真的在嵌套代码的一个僻静的角落找到了一个缺少的等待语句,正如@Charlieface所说,非常感谢大家!

您的代码中显然缺少 await,这导致异常被包裹在 AggregateException.

await 所做的其中一件事,以及设置状态机,就是解包 AggregateExceptions,它包含在 运行 期间抛出的任何异常Task。因此,如果要捕获并处理特定的异常类型,应该使用await一路往下。