C# 在Linq表达式中使用Async/Await不会引发异常
晚上, 有人能告诉我为什么使用async和await运算符的linq语句不会向堆栈上传播异常,而foreach循环会传播异常?一定有什么东西在引擎盖下,并记录在某个地方的这种行为,我只是没有运气找到它#googlefoofail#doyouevenasyncbrah 如果运行单元测试,您将看到它返回时没有错误且有效。但是,如果调试单元测试,它将在出现错误时中断,但是它将允许您继续,并且该错误不会传播到堆栈中 如果注释掉linq语句并取消对foreach循环的注释,则在尝试向字典添加重复键时会出现预期的错误C# 在Linq表达式中使用Async/Await不会引发异常,c#,linq,exception,async-await,C#,Linq,Exception,Async Await,晚上, 有人能告诉我为什么使用async和await运算符的linq语句不会向堆栈上传播异常,而foreach循环会传播异常?一定有什么东西在引擎盖下,并记录在某个地方的这种行为,我只是没有运气找到它#googlefoofail#doyouevenasyncbrah 如果运行单元测试,您将看到它返回时没有错误且有效。但是,如果调试单元测试,它将在出现错误时中断,但是它将允许您继续,并且该错误不会传播到堆栈中 如果注释掉linq语句并取消对foreach循环的注释,则在尝试向字典添加重复键时会出现
[TestMethod]
公共空间测试器()
{
列表对=新列表()
{
{new KeyValuePair(“test”,“first”)},
{新的KeyValuePair(“test”,“second”)}
};
失败=新建字典();
ForEach(异步x=>await-testasync(x))//
有人能告诉我为什么使用async和await运算符的linq语句不会向堆栈上传播异常,而foreach循环会传播异常
实际上,它不是LINQ语句;它是List.ForEach
List.ForEach
不与async
lambdas一起工作,因为它只需要void
-返回委托类型,而不是任务
-返回委托类型。因此async
lambda成为async void
方法
有人能告诉我为什么使用async和await运算符的linq语句不会向堆栈上传播异常,而foreach循环会传播异常
实际上,它不是LINQ语句;它是列表。ForEach
列表。ForEach
不与async
lambdas一起工作,因为它只需要void
返回委托类型,而不是任务
返回委托类型。因此async
lambda成为async void
方法,这就是。用来解释的n您看到的行为。关键摘录:
当异步运行的任务引发异常时,该任务将出错。任务对象保存在task.exception属性中引发的异常。出现故障的任务在等待时引发异常
由于您从未等待Lambda的结果,因此从未引发结果任务中存储的异常。您可以执行以下任一操作来修复该问题:
// more equivalent to your `foreach` loop.
pairs.ForEach(x => testasync(x).GetAwaiter().GetResult());
Task.WhenAll(pairs.Select(async x => await testasync(x))).GetAwaiter().GetResult();
// preferred
await Task.WhenAll(pairs.Select(async x => await testasync(x)));
最后一行是最好的方法,但是为了使用await
,您必须使调用方法异步,这意味着您应该将其更改为返回一个任务,调用它的任何人都应该await
返回的任务
,等等,直到整个调用链为止。这就是人们在嘿,说“一路异步”来解释你看到的行为。关键摘录:
当异步运行的任务引发异常时,该任务将出错。任务对象保存在task.exception属性中引发的异常。出现故障的任务在等待时引发异常
由于您从未等待Lambda的结果,因此从未引发结果任务中存储的异常。您可以执行以下任一操作来修复该问题:
// more equivalent to your `foreach` loop.
pairs.ForEach(x => testasync(x).GetAwaiter().GetResult());
Task.WhenAll(pairs.Select(async x => await testasync(x))).GetAwaiter().GetResult();
// preferred
await Task.WhenAll(pairs.Select(async x => await testasync(x)));
最后一行是最好的方法,但是为了使用await
,您必须使调用方法异步,这意味着您应该将其更改为返回一个任务,调用它的任何人都应该await
返回的任务
,等等,直到整个调用链为止。这就是人们在嘿,说“一路异步”。不确定文档,但这里提到的扩展方法可能会帮助您引发异常。不确定文档,但这里提到的扩展方法可能会帮助您引发异常。