深入理解 c# 第十五章 从任务失败重新包装多个异常

    class AggregatedExceptions
    {
        static void Main()//从任务失败重新包装多个异常
        {
            MainAsync().Wait();
        }

        private async static Task MainAsync()
        {
            Task task1 = Task.Run(() => { throw new Exception("Message 1"); });
			//Id = 2, Status = System.Threading.Tasks.TaskStatus.Faulted, Method = "{null}", Result = "{尚未计算}"
            Task task2 = Task.Run(() => { throw new Exception("Message 2"); });
			//$exception	{"Message 2"}	System.Exception 执行这句有异常
			//Id = 3, Status = System.Threading.Tasks.TaskStatus.WaitingForActivation, Method = "{null}", Result = "{尚未计算}"

            try
            {
                await Task.WhenAll(task1, task2);
            }
            catch (Exception e)
			//$exception	{"Message 1"}	System.Exception

            {
                Console.WriteLine("Caught {0}", e.Message);
            }

            try
            {
                await Task.WhenAll(task1, task2).WithAggregatedExceptions();
            }
            catch (AggregateException e)
            {
                Console.WriteLine("Caught {0} exceptions: {1}", e.InnerExceptions.Count,
                                  string.Join(", ", e.InnerExceptions.Select(x => x.Message)));
								  //x {"Message 1"}
            }
        }
    }
	
        public static AggregatedExceptionAwaitable WithAggregatedExceptions(this Task task)
        {
            if (task == null)
            {
                throw new ArgumentNullException("task");
            }

            return new AggregatedExceptionAwaitable(task);
        }

        public struct AggregatedExceptionAwaitable
        {
            private readonly Task task;

            internal AggregatedExceptionAwaitable(Task task)
			//task Id = 6, Status = System.Threading.Tasks.TaskStatus.Faulted, Method = "{null}", Result = "{尚未计算}"
            {
                this.task = task;
            }

            public AggregatedExceptionAwaiter GetAwaiter()
            {
                return new AggregatedExceptionAwaiter(task);
            }
        }

        public struct AggregatedExceptionAwaiter : ICriticalNotifyCompletion
        {
            private readonly Task task;

            internal AggregatedExceptionAwaiter(Task task)
            {
                this.task = task;
            }

            // Delegate most members to the task's awaiter
            public bool IsCompleted { get { return task.GetAwaiter().IsCompleted; } }

            public void UnsafeOnCompleted(Action continuation)
            {
 	            task.GetAwaiter().UnsafeOnCompleted(continuation);
            }

            public void OnCompleted(Action continuation)
            {
                task.GetAwaiter().OnCompleted(continuation);
            }

            public void GetResult()
            {
                // This will throw AggregateException directly on failure,
                // unlike task.GetAwaiter().GetResult()
                task.Wait();
            }
        }
		


  编写一个Task<T>的扩展方法,从而创建一个可从任务中抛出原始AggregateException
的特殊可等待模式成员。  
  Task<T>也需要一个类似的方法,即在GetResult()中使用return task.Result,而不是
调用Wait()。我们想自己不想处理的部分委托给了任务的awaiter,而回避了GetResult()
常规行为,即对异常进行拆包。在调用GetResult时,我们知道任务处于即将结束的状态,
因此Wait()调用可立即返回。 
  WithAggregatedExceptions()返回自定义的可等待模式成员,而后者的GetAWaiter()

又提供自定义的awaiter,并支持C#编译器所需要的操作来等待结果。  


输出
Caught Message 1
Caught 2 exceptions: Message 1, Message 2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值