• 任务工厂


     1         private static void TaskFactoryDemo()
     2         {
     3             Task taskParent = new Task(() =>
     4             {
     5                 //向应该被取消的 System.Threading.CancellationToken 发送信号。
     6                 CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
     7 
     8                 //提供对创建和计划 Task<TResult> 对象的支持。
     9                 //   cancellationToken:
    10                 //     将指派给由此 System.Threading.Tasks.TaskFactory 创建的任务的默认取消标记(除非在调用工厂方法时显式指定另一个取消标记)。
    11                 //
    12                 //   creationOptions:
    13                 //     在使用此 System.Threading.Tasks.TaskFactory<TResult> 创建任务时要使用的默认选项。
    14                 //
    15                 //   continuationOptions:
    16                 //     在使用此 System.Threading.Tasks.TaskFactory<TResult> 创建任务时要使用的默认选项。
    17                 //
    18                 //   scheduler:
    19                 //     要用于计划使用此 System.Threading.Tasks.TaskFactory<TResult> 创建的任何任务的默认计划程序。 null 值指示应使用 System.Threading.Tasks.TaskScheduler.Current。
    20                 TaskFactory<int> taskFactory = new TaskFactory<int>(cancellationTokenSource.Token, TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
    21 
    22                 //创建并启动3个子任务
    23                 //一个Task<int>类型的数组,初始化为3个返回类型为int的任务
    24                 Task<int>[] childTasks = new Task<int>[]{
    25 
    26                     //StartNew 创建并启动 任务。
    27                     taskFactory.StartNew(()=>Sum(cancellationTokenSource.Token,10000)),
    28                     taskFactory.StartNew(()=>Sum(cancellationTokenSource.Token,20000)),
    29                     //int.MaxValue 此处会抛出OverflowException
    30                     taskFactory.StartNew(()=>Sum(cancellationTokenSource.Token,int.MaxValue))
    31                 };
    32 
    33                 //循环给每一个子任务添加ContinueWith(延续任务)
    34                 for (int i = 0; i < childTasks.Length; i++)
    35                 {
    36                     //有任何一个子任务失败(OnlyOnFaulted),就取消(Cancel())所有子任务
    37                     childTasks[i].ContinueWith(t => cancellationTokenSource.Cancel(), TaskContinuationOptions.OnlyOnFaulted);
    38                 }
    39 
    40                 //创建一个延续任务,它将在提供的一组任务全部完成(ContinueWhenAll)后马上开始。
    41                 // 参数:
    42                 //   tasks:
    43                 //     继续执行的任务所在的数组。
    44                 //
    45                 //   continuationFunction:
    46                 //     在 tasks 数组中的所有任务完成时要异步执行的函数委托。
    47                 //
    48                 //   cancellationToken:
    49                 //     将指派给新的延续任务的取消标记。
    50                 taskFactory.ContinueWhenAll(
    51                     childTasks,
    52                     //所有子任务均完成后,从未出错/未取消的子任务中获取返回的最大值
    53                     continuationFunction => continuationFunction.Where(t => !t.IsCanceled && !t.IsFaulted).Max(t => t.Result),
    54                     CancellationToken.None)
    55                     //将最大值传给另一个任务来显示最大结果
    56                     //(延续任务在导致前面的任务转换为其最终状态的相同线程上运行。 如果在创建延续任务时已经完成前面的任务,则延续任务将在创建此延续任务的线程上运行。)
    57                     //创建根据 continuationOptions 中指定的条件加以执行的延续任务。
    58                     //ExecuteSynchronously指定应同步执行延续任务。
    59                     .ContinueWith(t => Console.WriteLine("The maximum is:" + t.Result), TaskContinuationOptions.ExecuteSynchronously);
    60             });
    61 
    62             //子任务完成后也显示任何未处理的异常
    63             taskParent.ContinueWith(p =>
    64             {
    65                 //将所有文本放到一个StringBuilder中,并只调用Console.WriteLine
    66                 //这个任务可能和上面的任务并行执行,这样做可以避免输出变得不连续
    67                 StringBuilder stringBuilder = new StringBuilder("The following exception(s) occurred:" + Environment.NewLine);
    68                 //将 System.AggregateException 实例平展到一个新实例。
    69                 foreach (var e in p.Exception.Flatten().InnerExceptions)
    70                 {
    71                     stringBuilder.AppendLine(" " + e.GetType().ToString());
    72                 }
    73                 Console.WriteLine(stringBuilder.ToString());
    74             }, TaskContinuationOptions.OnlyOnFaulted);
    75 
    76             //启动父任务,使它能启动子任务
    77             taskParent.Start();
    78         }
    79 
    80         /// <summary>
    81         /// n以内正整数求和
    82         /// </summary>
    83         /// <param name="cancellationToken">取消操作的通知</param>
    84         /// <param name="n"></param>
    85         /// <returns></returns>
    86         private static int Sum(CancellationToken cancellationToken, int n)
    87         {
    88             int sum = 0;
    89             for (; n > 0; n--)
    90             {
    91                 //在取消标识引用的CancellationTokenSource上调用Cancel
    92                 //如果已请求取消此标记,则引发 System.OperationCanceledException
    93                 cancellationToken.ThrowIfCancellationRequested();
    94 
    95                 //检查n值,若太大,则抛出OverflowException
    96                 checked { sum = sum + n; }
    97             }
    98             return sum;
    99         }

          注意:调用TaskFactory或TaskFactory<TResult>的静态ContinueWhenAll和ContinueWhenAny方法时,无论前置任务是如何完成的,ContinueWhenAll和ContinueWhenAny都会执行延续任务。
  • 相关阅读:
    隐马尔科夫模型(HMM)
    各大IT企业招聘所须要求技能
    Java NIO和IO的主要差别
    Css 选择器总结
    程序猿生存定律-六个程序猿的故事(3)
    JVM学习心得
    APUE读书笔记-第14章-高级I/O
    《Word排版艺术》读后感,兼谈LaTeX
    LaTeX:Figures, Tables, and Equations 插入图表和公式
    LaTeX 的对参考文献的处理
  • 原文地址:https://www.cnblogs.com/xuejietong/p/8906915.html
Copyright © 2020-2023  润新知