internal ParallelQueue <ForeachPart <T, T1, T2> > FillWithForeachPart <T, T1, T2>(int from, int to, Action <T, T1, T2> action, IEnumerable <T> source, T1 value1, T2 value2) { ParallelQueue <ForeachPart <T, T1, T2> > parallelQueue = new ParallelQueue <ForeachPart <T, T1, T2> >(); int innercounter = 0; foreach (T sourceLocal in source) { if (innercounter >= from && innercounter <= to) { ForeachPart <T, T1, T2> foreachPart = new ForeachPart <T, T1, T2>(); foreachPart.Start = innercounter; foreachPart.End = innercounter; foreachPart.ExecutionPart = action; foreachPart.SingleSource = sourceLocal; foreachPart.Value1 = value1; foreachPart.Value2 = value2; parallelQueue.Enqueue(foreachPart); } else if (innercounter > to) { break; } innercounter++; } return(parallelQueue); }
public void ForeachExecution <T1, T2>(IEnumerable <T> source, Action <T, T1, T2> action, T1 value1, T2 value2) { int counter = 0; while (source.GetEnumerator().MoveNext()) { counter++; } chunk = counter / processorCount; int start = 0; int end = chunk; for (int i = 1; i <= processorCount; i++) { int x = i - 1; waitHandles[x] = new ManualResetEvent(false); ForeachPart <T, T1, T2> forEachPart = new ForeachPart <T, T1, T2>(); forEachPart.ExecutionPart = action; forEachPart.Source = source; forEachPart.Start = start; forEachPart.End = end; forEachPart.Value1 = value1; forEachPart.Value2 = value2; ConstantForeachSynchronisationContainer <T, T1, T2> foreachSynchronisationContainer = new ConstantForeachSynchronisationContainer <T, T1, T2>((ManualResetEvent)waitHandles[x], forEachPart); ThreadPool.QueueUserWorkItem( delegate(object state) { ConstantForeachSynchronisationContainer <T, T1, T2> forSynchronisationContainer = (ConstantForeachSynchronisationContainer <T, T1, T2>)state; ForeachPart <T, T1, T2> foreachPart = forSynchronisationContainer.ForEachPart_; try { int innercounter = 0; foreach (T sourceLocal in foreachPart.Source) { if (innercounter >= foreachPart.Start && innercounter <= foreachPart.End) { foreachPart.ExecutionPart.Invoke(ref innercounter, sourceLocal, foreachPart.Value1, foreachPart.Value2); } else if (innercounter > foreachPart.End) { break; } innercounter++; } } finally { forSynchronisationContainer.ManualResetEvent_.Set(); } }, foreachSynchronisationContainer); start = end + 1; end = end + chunk; } WaitHandle.WaitAll(waitHandles); }
public void ForeachExecution(IEnumerable <T> source, Action <T> action, ExecutionConstancyEnum executionConstancy) { if (executionConstancy == ExecutionConstancyEnum.Constant) { ForeachExecution(source, action); } else { ParallelQueue <ForeachPart <T> >[] parallelQueues = new ParallelQueue <ForeachPart <T> > [processorCount]; int counter = 0; while (source.GetEnumerator().MoveNext()) { counter++; } chunk = counter / processorCount; int start = 0; int end = chunk; for (int i = 1; i <= processorCount; i++) { int x = i - 1; waitHandles[x] = new ManualResetEvent(false); ParallelQueueFiller parallelQueueFiller = new ParallelQueueFiller(); ParallelQueue <ForeachPart <T> > parallelQueue = parallelQueueFiller.FillWithForeachPart <T>(start, end, action, source); parallelQueues[x] = parallelQueue; UnconstantForeachSynchronisationContainer <T> unconstantForeachSynchronisationContainer = new UnconstantForeachSynchronisationContainer <T>((ManualResetEvent)waitHandles[x], parallelQueue, parallelQueues); ThreadPool.QueueUserWorkItem( delegate(object state) { UnconstantForeachSynchronisationContainer <T> localUnconstantForeachSynchronisationContainer = (UnconstantForeachSynchronisationContainer <T>)state; ParallelQueue <ForeachPart <T> > localparallelQueue = localUnconstantForeachSynchronisationContainer.ParallelQueue; ParallelQueue <ForeachPart <T> >[] localparallelQueues = localUnconstantForeachSynchronisationContainer.ParallelQueues; try { bool localQueueIsEmpty = false; while (!localQueueIsEmpty) { ForeachPart <T> foreachPart = localparallelQueue.Dequeue(); if (foreachPart != null) { int ii = foreachPart.Start; foreachPart.ExecutionPart.Invoke(ref ii, foreachPart.SingleSource); } else { localQueueIsEmpty = true; } } foreach (ParallelQueue <ForeachPart <T> > localForegnParallelQueue in localparallelQueues) { if (localForegnParallelQueue != localparallelQueue) { bool localForegnQueueIsEmpty = false; while (!localForegnQueueIsEmpty) { ForeachPart <T> foreachPart = localForegnParallelQueue.Steal(); if (foreachPart != null) { int ii = foreachPart.Start; foreachPart.ExecutionPart.Invoke(ref ii, foreachPart.SingleSource); } else { localForegnQueueIsEmpty = true; } } } } } finally { localUnconstantForeachSynchronisationContainer.ManualResetEvent_.Set(); } }, unconstantForeachSynchronisationContainer); start = end + 1; end = end + chunk; } WaitHandle.WaitAll(waitHandles); } }
public ConstantForeachSynchronisationContainer(ManualResetEvent manualResetEvent, ForeachPart <T> forEeachPart) : base(manualResetEvent) { this.forEeachPart_ = forEeachPart; }