c# - 为什么带有异常的异步任务会成功完成?
问题描述
我有一个 C# 控制台应用程序,其中包含许多异步任务。其中一项任务是引发异常。但是,我了解到主机代码没有按预期处理场景。为了了解发生了什么,我决定进行一次测试。这个测试的目的是创建一个Task
异步运行的,但是,故意抛出一个异常。我想看看返回的内容是否与主机代码的预期相符。
令我惊讶的是,Task
对象的IsCompletedSuccessfully
属性是true
并且IsFaulted
属性是false
。然而,我期待IsCompletedSuccessfully
成为false
和IsFaulted
成为true
。代码如下所示:
[Fact]
public void Repro()
{
var task = new Task(async () => {
var operand1 = 2;
var operand2 = 0;
var result = operand1 / operand2;
Thread.Sleep(250);
await Task.CompletedTask;
});
task.RunSynchronously();
Console.WriteLine($"Cancelled: {task.IsCanceled}, Completed: {task.IsCompleted}, Completed Successfully: {task.IsCompletedSuccessfully}, Faulted: {task.IsFaulted}");
if (task.Exception != null)
{
Console.WriteLine("There was an exception");
}
Assert.Equal(false, task.IsCompletedSuccessfully);
Assert.Equal(true, task.IsFaulted);
}
为什么/如何成功完成此任务?为什么它没有故障?我期待它会引发除以零异常。
谢谢你。
解决方案
没有Task
采用 a 的构造函数Func<Task>
:唯一的重载采用Action
or Action<object>
。
因此,当您编写时new Task(async () => ...)
,那里的异步 lambda 需要编译为async void
方法。
请注意void
: 无法将Task
备份传播给调用者,这意味着Task
构造的 withnew Task(...)
仅在 lambda 直接抛出异常时才知道是否存在异常。但是,由于 lambda 是async void
,它不会向调用者抛出异常!但是,它会将它们重新扔到线程池中,这会使您的应用程序崩溃。
推荐阅读
- javascript - Reducer 突然在商店中添加商品
- python - UnicodeEncodeError:“ascii”编解码器无法在位置 37 编码字符“\u201c”:序数不在范围内(128)
- firebase - 安装 Firebase CLI 时出现意外的 Json
- c# - 更改数据库中的数据时列表框不刷新
- python - 运行 conda clean 但文件存在时出现 Filenotfound 错误
- c++ - 为什么当我的程序在 Linux 上运行时 splice syscall 失败,但在 gdb 中运行时成功?
- python - 在 tkinter 中调整图像大小
- javascript - Dropzone.js 添加其他数据时不发送文件
- java - JDK 8 中的正则表达式中的错误?
- three.js - 如何创建多色噪波着色器