为什么在 C# 中处理 TaskFactory 的异常如此困难

Why handling TaskFactory's Exception so difficult in C#

案例 1:

        var cts = new CancellationTokenSource();
        var tf = new TaskFactory(cts.Token,
            TaskCreationOptions.AttachedToParent,
            TaskContinuationOptions.ExecuteSynchronously,
            TaskScheduler.Default);
        var childTasks = new Task[2];
        childTasks[0] = tf.StartNew(async () =>
        {

        }, TaskCreationOptions.LongRunning);
        childTasks[1] = tf.StartNew(() =>
        {
            throw new Exception("dddddd");
        });
        try
        {
            Task.WaitAll(childTasks);
        }
        catch (AggregateException ae)
        {
            foreach (var e in ae.Flatten().InnerExceptions)
            {
                Console.WriteLine(e);
            }
        }

有效。

案例 2:

       ....same as 1....
        childTasks[1] = tf.StartNew(async () =>
        {
            throw new Exception("dddddd");
        });
       ....same as 1....

不work.The只是"async"

的区别

案例 3:

            childTasks[1] = tf.StartNew( () =>
            {
                throw new Exception("dd");
                //await b();
            }).ContinueWith((t) => { Console.WriteLine(t.Exception); }, TaskContinuationOptions.OnlyOnFaulted);

有效。

案例 4:

            childTasks[1] = tf.StartNew(async () =>
            {
                //throw new Exception("dd");
                await b();
            });
            try
            {
                Task.WaitAll(childTasks);
            }
            catch (AggregateException ae)
            {
                foreach (var e in ae.Flatten().InnerExceptions)
                {
                    Console.WriteLine(e);
                }
            }
    private static async Task b()
    {

            throw new NullReferenceException("未将你妈绑定到实例");
             await ........
    }

没有work.The异常不写。

太奇怪了!我想要的只是一个地方可以一起处理所有这些异常。但是我failed.Is有人知道如何处理这种情况吗?请帮助我,我感觉我快疯了!

您的问题是由于 StartNew 没有 async 感知。这是one of the reasons to avoid StartNew that I describe on my blog.

简而言之,您没有看到异常的原因是因为将 async lambda 传递给 StartNew 将 return 一个 Task<Task> 而不是普通的 Task,您需要 Unwrap 嵌套任务才能获得 async 方法的结果。

您可以像这样打开任务:

childTasks[1] = tf.StartNew(async () =>
{
  throw new Exception("dddddd");
}).Unwrap();