TaskFactory

作者:追风剑情 发布于:2017-10-19 11:58 分类:C#

示例

  1. using System;
  2. using System.Text;
  3. using System.Linq;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6.  
  7. namespace TaskTest2
  8. {
  9. class Program
  10. {
  11. static void Main(string[] args)
  12. {
  13. Task parent = new Task(() =>
  14. {
  15. var cts = new CancellationTokenSource();
  16. // 利用任务工厂可以创建一组共享相同配置的任务
  17. var tf = new TaskFactory<Int32>(
  18. cts.Token,
  19. //用此工厂创建的所有任务都将被视为子任务
  20. TaskCreationOptions.AttachedToParent,
  21. //延续任务在前置任务所在的线程运行,
  22. //如果前置任务已经执行完成,则在创建它的线程中运行
  23. TaskContinuationOptions.ExecuteSynchronously,
  24. //采用默认调度器
  25. TaskScheduler.Default);
  26.  
  27. // 这个任务创建并启动3个子任务
  28. var childTasks = new[]{
  29. tf.StartNew(()=>Sum(cts.Token, 10000)),
  30. tf.StartNew(()=>Sum(cts.Token, 20000)),
  31. //tf.StartNew(()=>Sum(cts.Token, Int32.MaxValue))//太大,抛出OverflowException
  32. };
  33.  
  34. // 任何子任务抛出异常,就取消其余子任务
  35. for (Int32 task = 0; task < childTasks.Length; task++)
  36. childTasks[task].ContinueWith(t => cts.Cancel(), TaskContinuationOptions.OnlyOnFaulted);
  37.  
  38. // 所有子任务完成后,从未出错/未取消的任务获取返回的最大值
  39. // 然后将最大值传递给另一个任务来显示最大结果
  40. tf.ContinueWhenAll(
  41. childTasks,
  42. //必须引入System.Linq命名空间,否则会报Where未定义。
  43. completedTasks => completedTasks.Where(
  44. t => !t.IsFaulted && !t.IsCanceled).Max(t => t.Result),
  45. //覆盖TaskFactory的CancellationToken
  46. //这里传None是为了子任务被取消后,此任务依然可以执行
  47. CancellationToken.None)
  48. .ContinueWith(t => Console.WriteLine("The maximum is: "+t.Result),
  49. TaskContinuationOptions.ExecuteSynchronously);
  50. });
  51.  
  52. // 子任务完成后,也显示任何未处理的异常
  53. parent.ContinueWith(p =>
  54. {
  55. StringBuilder sb = new StringBuilder(
  56. "The following exception(s) occurred:" + Environment.NewLine);
  57.  
  58. foreach (var e in p.Exception.Flatten().InnerExceptions)
  59. sb.AppendLine(" " + e.GetType().ToString());
  60. Console.WriteLine(sb.ToString());
  61. },
  62. TaskContinuationOptions.OnlyOnFaulted);
  63.  
  64. // 启动父任务
  65. parent.Start();
  66.  
  67. Console.ReadLine();
  68. }
  69.  
  70. private static Int32 Sum(CancellationToken ct, Int32 n)
  71. {
  72. Int32 sum = 0;
  73. for (; n > 0; n--)
  74. {
  75. //在取消标志引用的CancellationTokenSource上调用Cancel,
  76. //下面这行代码就会抛出OperationCanceledException
  77. ct.ThrowIfCancellationRequested();
  78.  
  79. //如果n太大,会抛出System.OverflowException
  80. checked { sum += n; }
  81. }
  82. return sum;
  83. }
  84. }
  85. }

运行测试

111.png

标签: C#

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号