Parallel——执行并行任务

作者:追风剑情 发布于:2017-11-8 21:57 分类:C#

示例


  1. using System;
  2. using System.IO;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading;
  7. using System.Threading.Tasks;
  8.  
  9. //参考 https://www.cnblogs.com/ricky-wang/p/7003162.html
  10. namespace Test3
  11. {
  12. class Program
  13. {
  14. static void Main(string[] args)
  15. {
  16. //Parallel调用线程池中的线程并性处理工作,Parallel内部会创建Task
  17. //Parallel.For的执行效率高于Parallel.ForEach
  18. //Parallel内部是并行执行,但For或ForEach方法会使调用线程挂起(即,同步执行),直到所有工作完成。
  19. //如果任何操作抛出未处理的异常,For或ForEach方法会抛出AggregateException
  20. ParallelLoopResult result = Parallel.For(0, 10, (i, state) => DoWork(i, state));
  21. Console.WriteLine("是否完成:{0}", result.IsCompleted);
  22. Console.WriteLine("最低迭代:{0}", result.LowestBreakIteration);
  23. //如果IsCompleted=false,LowestBreakIteration!=null表示某工作项调用了Break
  24. //如果IsCompleted=true,LowestBreakIteration=null表示某工作项调用了Stop
  25.  
  26. //Parallel.ForEach用来遍历集合
  27. string[] data = { "str1", "str2", "str3", "str4", "str5" };
  28. result = Parallel.ForEach<string>(data, (str, state, i) =>
  29. {
  30. Console.WriteLine("迭代次数:{0},{1}", i, str);
  31. if (i > 3)
  32. state.Break();
  33. //state.Break() 不再处理当前项之后的项
  34. //state.Stop() 停止处理任何更多的工作
  35. //state.IsExceptional true:其他工作项抛出了未处理异常
  36. });
  37. Console.WriteLine("是否完成:{0}", result.IsCompleted);
  38. Console.WriteLine("最低迭代:{0}", result.LowestBreakIteration);
  39.  
  40. //Parallel.Invoke用于执行并行任务
  41. Parallel.Invoke(() =>
  42. {
  43. Thread.Sleep(100);
  44. Console.WriteLine("method1");
  45. }, () =>
  46. {
  47. Thread.Sleep(10);
  48. Console.WriteLine("method2");
  49. });
  50.  
  51. //利用Parallel.ForEach统计某个目录下的文件大小
  52. long masterTotal = DirectoryBytes(@"E:\", "*.jpg", SearchOption.TopDirectoryOnly);
  53. Console.WriteLine("File TotalSize={0}KB", masterTotal);
  54. Console.ReadLine();
  55. }
  56.  
  57. private static void DoWork(int i, ParallelLoopState state)
  58. {
  59. Console.WriteLine("DoWork({0}): 任务ID={1}, 线程ID={1}", i,
  60. Task.CurrentId,
  61. Thread.CurrentThread.ManagedThreadId);
  62. Thread.Sleep(10);
  63. if (i > 5)
  64. state.Break();//result.LowestBreakIteration的值为此时的i
  65. }
  66.  
  67. private static Int64 DirectoryBytes(String path, String searchPattern, SearchOption searchOption)
  68. {
  69. var files = Directory.EnumerateFiles(path, searchPattern, searchOption);
  70. Int64 masterTotal = 0;
  71.  
  72. ParallelLoopResult result = Parallel.ForEach<String, Int64>(
  73. files,
  74. () =>//localInit: 每个任务开始之前调用一次
  75. {
  76. //每个任务开始之前,总计值都初始化为0
  77. return 0;
  78. },
  79. (file, loopState, index, taskLocalTotal) =>//body: 每个工作项调用一次
  80. {
  81. //获得这个文件的大小,把它添加到这个任务的累加值上
  82. Int64 fileLength = 0;
  83. FileStream fs = null;
  84. try
  85. {
  86. fs = File.OpenRead(file);
  87. fileLength = fs.Length;
  88. }
  89. catch (IOException) { /*忽略拒绝访问的任何文件*/ }
  90. finally { if (fs != null) fs.Dispose(); }
  91. return taskLocalTotal + fileLength;
  92. },
  93. taskLocalTotal =>//localFinally: 每个任务完成时调用一次
  94. {
  95. //将这个任务的总计算(taskLocalTotal)加到总的总计值(masterTotal)上
  96. //保证线程安全
  97. Interlocked.Add(ref masterTotal, taskLocalTotal);
  98. });
  99.  
  100. return masterTotal;
  101. }
  102. }
  103. }


运行测试

1111.png

标签: C#

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号