C#-Parallel

  1 using System;
  2 using System.Collections.Concurrent;
  3 using System.Collections.Generic;
  4 using System.Linq;
  5 using System.Threading;
  6 using System.Threading.Tasks;
  7 
  8 namespace Try
  9 {
 10     public class ParallelTest
 11     {
 12         #region 分区块并行执行
 13         public static void TestPartition()
 14         {
 15             var datas = Enumerable.Range(0, 100000).ToList();
 16             PartitionByPartCount(datas,5);
 17             PartitionByPartSize(datas,100);
 18         }
 19 
 20         private static void PartitionByPartCount<T>(IList<T> datas, int partCount)
 21         {
 22             var partSize = (int)Math.Ceiling(datas.Count / (double)partCount);
 23             var partitioner = Partitioner.Create(0, datas.Count, partSize);
 24             Parallel.ForEach(partitioner, (part, state, partIndex) => {
 25                 for (int index = part.Item1; index < part.Item2; index++)
 26                 {
 27                     Console.WriteLine($"partIndex:{partIndex},index:{index},data:{datas[index]}");
 28                 }
 29             });
 30         }
 31 
 32         private static void PartitionByPartSize<T>(IList<T> datas, int partSize)
 33         {
 34             var partitioner = Partitioner.Create(0, datas.Count, partSize);
 35             Parallel.ForEach(partitioner, (part, state, partIndex) => {
 36                 for (int index = part.Item1; index < part.Item2; index++)
 37                 {
 38                     Console.WriteLine($"partIndex:{partIndex},index:{index},data:{datas[index]}");
 39                 }
 40             });
 41         }
 42         #endregion
 43 
 44         #region 取消Parallel
 45         public static void TestCancel()
 46         {
 47             int[] nums = Enumerable.Range(0, 10000000).ToArray();
 48             CancellationTokenSource cts = new CancellationTokenSource();
 49 
 50             // Use ParallelOptions instance to store the CancellationToken
 51             ParallelOptions po = new ParallelOptions();
 52             po.CancellationToken = cts.Token;
 53             po.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
 54             Console.WriteLine("Press any key to start. Press 'c' to cancel.");
 55             Console.ReadKey();
 56 
 57             // Run a task so that we can cancel from another thread.
 58             Task.Factory.StartNew(() =>
 59             {
 60                 if (Console.ReadKey().KeyChar == 'c')
 61                     cts.Cancel();
 62                 Console.WriteLine("press any key to exit");
 63             });
 64 
 65             try
 66             {
 67                 Parallel.ForEach(nums, po, (num) =>
 68                 {
 69                     double d = Math.Sqrt(num);
 70                     Console.WriteLine("{0} on {1}", d, Thread.CurrentThread.ManagedThreadId);
 71                     po.CancellationToken.ThrowIfCancellationRequested();
 72                 });
 73             }
 74             catch (OperationCanceledException e)
 75             {
 76                 Console.WriteLine(e.Message);
 77             }
 78             finally
 79             {
 80                 cts.Dispose();
 81             }
 82 
 83             Console.ReadKey();
 84         }
 85         #endregion
 86 
 87         #region 异常处理
 88         public static void TestException()
 89         {
 90             // Create some random data to process in parallel.
 91             // There is a good probability this data will cause some exceptions to be thrown.
 92             byte[] data = new byte[5000];
 93             Random r = new Random();
 94             r.NextBytes(data);
 95 
 96             try
 97             {
 98                 ProcessDataInParallel(data);
 99             }
100             catch (AggregateException ae)
101             {
102                 var ignoredExceptions = new List<Exception>();
103                 // This is where you can choose which exceptions to handle.
104                 foreach (var ex in ae.Flatten().InnerExceptions)
105                 {
106                     if (ex is ArgumentException)
107                         Console.WriteLine(ex.Message);
108                     else
109                         ignoredExceptions.Add(ex);
110                 }
111                 if (ignoredExceptions.Count > 0) throw new AggregateException(ignoredExceptions);
112             }
113 
114             Console.WriteLine("Press any key to exit.");
115             Console.ReadKey();
116         }
117 
118         private static void ProcessDataInParallel(byte[] data)
119         {
120             // Use ConcurrentQueue to enable safe enqueueing from multiple threads.
121             var exceptions = new ConcurrentQueue<Exception>();
122 
123             // Execute the complete loop and capture all exceptions.
124             Parallel.ForEach(data, d =>
125             {
126                 try
127                 {
128                     // Cause a few exceptions, but not too many.
129                     if (d < 3)
130                         throw new ArgumentException($"Value is {d}. Value must be greater than or equal to 3.");
131                     else
132                         Console.Write(d + " ");
133                 }
134                 // Store the exception and continue with the loop.                    
135                 catch (Exception e)
136                 {
137                     exceptions.Enqueue(e);
138                 }
139             });
140             Console.WriteLine();
141 
142             // Throw the exceptions here after the loop completes.
143             if (exceptions.Count > 0) throw new AggregateException(exceptions);
144         }
145         #endregion
146     }
147 }
原文地址:https://www.cnblogs.com/LaughAtSelfsWrong/p/11531630.html