C# Task.When任何未观察到的异常

C# Task.When任何未观察到的异常,c#,.net,task-parallel-library,.net-4.5,async-await,C#,.net,Task Parallel Library,.net 4.5,Async Await,假设我有三个任务,a,b,和c。所有三个都保证在1到5秒之间的随机时间抛出异常。然后我编写以下代码: await Task.WhenAny(a, b, c); 这将最终从最先出现故障的任务引发异常。因为这里没有try…catch,所以这个异常会出现在我的代码中的其他地方 当剩下的两个任务抛出异常时会发生什么?这些未被观察到的异常是否会导致整个过程被终止?这是否意味着当任何位于try…catch块内时,只有这样才能使用,然后在继续之前以某种方式观察剩余的两个任务 跟进:我希望答案同时适用于带有异

假设我有三个任务,
a
b
,和
c
。所有三个都保证在1到5秒之间的随机时间抛出异常。然后我编写以下代码:

await Task.WhenAny(a, b, c);
这将最终从最先出现故障的任务引发异常。因为这里没有
try…catch
,所以这个异常会出现在我的代码中的其他地方

当剩下的两个任务抛出异常时会发生什么?这些未被观察到的异常是否会导致整个过程被终止?这是否意味着当任何位于
try…catch
块内时,只有这样才能使用
,然后在继续之前以某种方式观察剩余的两个任务


跟进:我希望答案同时适用于带有异步目标包的.NET 4.5和.NET 4.0(尽管在这种情况下使用
TaskEx.wheny

是的,其余的任务异常未被发现。在.NET4.5之前,您必须观察它们(不确定.NET4.5上的情况如何,但它发生了变化)

我通常为自己编写一个fire and forget任务的助手方法,例如:

    public static void IgnoreUnobservedExceptions(this Task task)
    {
        if (task.IsCompleted)
        {
            if (task.IsFaulted)
            {
                var dummy = task.Exception;
            }
            return;
        }

        task.ContinueWith(t =>
            {
                var dummy = t.Exception;
            }, TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);
    }
您可能希望包括登录生产应用程序

当剩下的两个任务抛出异常时会发生什么

这些
任务将在故障状态下完成

这些未被观察到的异常是否会导致整个过程被终止

不再是了

在.NET4.0中,
任务
析构函数将其未观察到的异常传递给,如果未经处理,将终止进程


在.NET4.5中,这个。现在,未观察到的异常被传递到任务调度器。未观察到的任务异常
,但如果未处理,它们将被忽略。

您是否尝试运行代码以查看会发生什么情况?@servey终结器没有抛出,但我看不到不抛出的好理由。我想您是指
任务。whenay(),
等待任务。WaitAny()
甚至不会编译。这里有一个错误的前提:
任务。任何时候
任务。WaitAny
都不会抛出异常。@DavidFeffer我不这么认为。当任何
未抛出时,等待从
返回的任务。它返回导致WhenAny运行完成的任务,等待该任务将抛出.NET 4.0,但这也不会终止终结器中的进程,我不知道为什么。如果安装了.NET 4.5,即使目标是.NET 4.0,您也在.NET 4.5上运行。那么示例代码在.NET 4.0上确实失败了吗?有没有办法在我的(4.5)dev计算机上重现这种行为?我相信异步目标包实际上会添加一个
UnobservedTaskeException
处理程序来防止进程终止(我没有测试过这一点,但这是.NET 4.0的异步CTP的行为),所以任何使用
的时候
都会有相同的行为。要使.NET 4.5模仿旧的.NET 4.0行为,还有很多方法。@KFL:
wait Task.WaitAny(…)
让您完成第一个任务;为了观察该任务,您可以使用第二个wait:
wait-wait任务。然而,在.NET4.0上,当有(…)
时,这也不会终止终结器中的进程,我不知道为什么。