5

我不是悄悄吞下异常的忠实拥护者,但下面的代码正是这样做的:

Task.Run(() =>
{
    var obj = DoSomethingCpuIntensive(); // returns null, due to a bug
    obj.DoMoreStuff();
    Console.WriteLine("after"); // never get here; program continues running
});

我已经阅读了有关ThrowUnobservedTaskExceptions配置值的信息,但这并没有帮助,因为我从未对Task返回的内容做任何事情(编辑:实际上它确实有帮助,但仅在发布版本中)。

有没有办法让这个未处理的异常使程序崩溃?我是否以Task.Run不应该的方式使用?

4

3 回答 3

2

我强烈建议您使用Task.Runover ThreadPool.QueueUserWorkItem

首先,退后一步。的目的是DoSomethingCpuIntensive什么?如果您正在计算某个值,我建议您将其返回,这样您就有 aTask<T>而不是 a Task。例如,(假设DoMoreStuff不是 CPU 密集型的):

async Task DoWorkAsync()
{
  var obj = await Task.Run(() => DoSomethingCpuIntensive());
  obj.DoMoreStuff();
}

我试图传达的想法是,您的代码应该关心后台操作的结果,即使“结果”只是“成功”或“异常”。这样你的代码就更干净了。否则,您将拥有一个半独立的系统,您只能通过检测应用程序状态的变化来做出响应。更乱。

也就是说,如果您确实想要拥有半独立系统并且希望它在失败时使您的进程崩溃,那么ThrowUnobservedTaskExceptions这正是您想要的。我不确定你为什么认为它没有帮助。

于 2013-04-25T12:44:07.710 回答
1

看起来Task.Run像这样使用确实是一个错误。我想我应该这样await做,否则会发生上述愚蠢的事情。

当它与 . 一起崩溃时await,调试器相当无用,如下所示:

                在此处输入图像描述

我认为这一切意味着我真的在Task.Run这里做错了。

一个简单的解决方法是改用旧的ThreadPool.QueueUserWorkItem

                  在此处输入图像描述

那好多了!无论如何,我在这段代码中并不真的需要 async/await;我只是使用Task.Run它,因为它打字少。

于 2013-04-25T11:16:44.760 回答
0

你说你读过ThrowUnobservedTaskExceptions;你真的试过在你的配置中ThrowUnobservedTaskExceptions运行你的程序吗?true

.NET 4 中的默认行为是未观察到Task的异常将导致整个过程中断。

.NET 4.5 中的默认行为是未观察到的Task异常不会导致进程中断。由于您在 .NET 4.5 上运行,因此设置ThrowUnobservedTaskExceptionstrue应该完全符合您的要求。

于 2013-04-25T12:42:30.370 回答