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
一路往下。
以下代码在(.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
一路往下。