static void Run <T>(IEnumerable <IndexedValue <T> > items, DegreeOfParallelism degreeOfParallelism, CancellationToken cancellationToken = default) { IOrderedQueue <IndexedValue <T> > orderedQueue = new LockFreeOrderedQueue <IndexedValue <T> >((x, y) => x.Index.CompareTo(y.Index)); var enqueuingCompleted = false; using var consumerLinkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); using var producersLinkedCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); var queueWorker = new Thread(() => { try { HandleOrderedQueue(orderedQueue, () => enqueuingCompleted, producersLinkedCancellationTokenSource.Token); } catch (OperationCanceledException) { // ignore this one } catch (Exception) { consumerLinkedCancellationTokenSource.Cancel(); } }); queueWorker.Start(); var encodingExceptions = ParallelExecution.ForEach( items, handleItem: item => { // if (item.Index == 27) { throw new Exception("!!!ParallelExecution!!!T_T"); } Console.WriteLine($"{Thread.CurrentThread.Name}: starts working on item {item.Index}"); // emulate encoding work Thread.Sleep(300); // * (item.Index % 2 == 0 ? 4 : 1)); // Console.WriteLine($"{Thread.CurrentThread.Name}: ends working on item {item.Index}"); orderedQueue.Enqueue(item); Semaphore.Release(); }, degreeOfParallelism, consumerLinkedCancellationTokenSource.Token); enqueuingCompleted = true; if (encodingExceptions.Count > 0) { if (!encodingExceptions.OfType <OperationCanceledException>().Any()) { producersLinkedCancellationTokenSource.Cancel(); } LogEncodingExceptions(encodingExceptions); } queueWorker.Join(); }
public static void TestCustom <T>(IEnumerable <IndexedValue <T> > items, DegreeOfParallelism degreeOfParallelism) { Console.WriteLine("Start testing Custom"); var sw = Stopwatch.StartNew(); ParallelExecution.ForEach(items, item => { Console.WriteLine($"{Thread.CurrentThread.Name} : takes item {item.Index}"); Thread.Sleep(200); }, degreeOfParallelism); sw.Stop(); Console.WriteLine("End testing Custom"); Console.WriteLine($"ms: {sw.ElapsedMilliseconds}, ticks: {sw.ElapsedTicks}"); }