1

如果我在下面的示例中取消注释行,Wait()startNew.Result将捕获AggregateException. 如果这些代码行被注释,为什么我看不到任何异常?

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Task<int> startNew = Task.Factory.StartNew(() => int.Parse(""), 
                                             TaskCreationOptions.LongRunning);
            //int result = startNew.Result;
            //startNew.Wait();
            Thread.Sleep(10000);             
        }
        catch (AggregateException ex)
        {
            Console.WriteLine("Catched in aggregated");
        }
        catch (Exception)
        {
            Console.WriteLine("Catched in general");
        }

        Console.WriteLine("The end");
        Console.ReadLine();
    }
}
4

2 回答 2

2

但是,如果这些代码行被注释,为什么我看不到任何异常?

因为没有什么东西可以扔掉它们!您真的不希望一个线程的异常在任意点被抛出到另一个线程中,而不需要您做任何事情来导致它。

Task<> 记住异常,但它不会抛出它们,除非您专门执行诸如Wait()or之类的操作Result,如您所见。

您还可以使用Task.Exception.

于 2012-12-18T12:02:46.397 回答
0

Jon Skeet 是对的,但他的回答并不完整。

我应该补充一点,如果您不调用 Wait() 或 Result,那么您可能会遇到在 Task 对象上调用 Finalize 方法的情况,并且该调用将检查内部任务对象异常集合中是否存在异常,然后抛出UnobservedTaskException 导致应用程序立即崩溃的原因(只要您不为 TaskScheduler.UnobservedTaskException 注册回调,强烈不建议这样做)。

于 2012-12-19T10:18:25.700 回答