任务工厂

有时候需要创建一组共享相同配置的Task对象,为了避免重复的将相同的参数传给每个Task,创建一个任务工厂很有必要

 static void Main(string[] args)
        {
            //父任务
            Task parent = new Task(
               () =>
               {
                   var cts = new CancellationTokenSource();  //标志

                   //任务工厂
                   var tf = new TaskFactory<int>(
                       cts.Token, TaskCreationOptions.AttachedToParent,
                       TaskContinuationOptions.ExecuteSynchronously,
                       TaskScheduler.Default
                       );
                   //创建子任务
                   var charltaske = new[]
                   {
                       //工厂任务直接开始一个 方法,因为是子任务所以,必须要父任务启动
                     tf.StartNew(()=>Sum(cts.Token,1000)),
                     tf.StartNew(()=>Sum(cts.Token,2000)),
                     tf.StartNew(()=>Sum(cts.Token,Int32.MaxValue))

                   };

                   //只要子任务其中的一个抛出异常,就取消全部的任务
                   for (int i = 0; i < charltaske.Length; i++)
                   {
                       charltaske[i].ContinueWith(t => {
                         cts.Cancel(); //所有任务终止,终止和失败都属于完成,到这里整个任务已经完成
                         Console.WriteLine("异常");
                       }, TaskContinuationOptions.OnlyOnFaulted);
                   }

                   //所有子任务完成后,查询出其中没有出错和取消的任务,并且返回最大值
                   //把最大的值传给另外一个任务来打印
                   //工厂任务调用ContinueWhenAll时 TaskContinuationOptions没有用,不管前置任务怎样都会执行
                   //ContinueWhenAll任务不属于子任务所以会和parent.ContinueWith同步执行,顺序会乱掉
                   tf.ContinueWhenAll(charltaske, compl => compl.Where(t => !t.IsFaulted && !t.IsCanceled).Max(t => t.Result),
                       CancellationToken.None).ContinueWith(t => Console.WriteLine("max is:" + t.Result)
                       , TaskContinuationOptions.None
                       );



               }); 
            //打印异常  整个任务执行的过车中如果有异常则运行这个方法
            parent.ContinueWith(
                p =>
                {


                    StringBuilder sb = new StringBuilder("occurrde:" + Environment.NewLine);
                    foreach (var item in p.Exception.Flatten().InnerExceptions)
                        sb.AppendLine("" + item.GetType().ToString());


                    Console.WriteLine(sb.ToString());


                }, TaskContinuationOptions.OnlyOnFaulted
                );






            parent.Start();   //父任务启动,子任务才会运行,这里是真正的启动任务,当所有子任务完成时,该任务才算完成


            Console.ReadLine(); 
}

 

 private static int Sum(CancellationToken cancellationToken, int p)
        {

            int sum = 0;
            try
            {
                for (int i = 0; i < p; i++)
                {
                    checked
                    {
                        sum += p;
                    }
                }
                Console.WriteLine("p=" + sum);
            }
            catch (Exception)
            {

              throw;
            }

            return sum;
        }

 

输出:

 

 

注意:如果调用多任务延续(即:调用TaskFactory或TaskFactory<TResult>的静态ContinueWhenAll和ContinueWhenAny方法)时,NotOn和On六个标识或标识的组合都是无效的。也就是说,无论先驱任务是如何完成的,ContinueWhenAll和ContinueWhenAny都会执行延续任务。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值