static ParallelLoopResult ForEach <TSource, TLocal> (Func <int, IList <IEnumerator <TSource> > > enumerable, ParallelOptions options, Func <TLocal> init, Func <TSource, ParallelLoopState, TLocal, TLocal> action, Action <TLocal> destruct) { if (SupportsParallelism) { return(Parallel.ForEach(enumerable, options, init, action, destruct)); } if (enumerable == null) { throw new ArgumentNullException("source"); } if (options == null) { throw new ArgumentNullException("options"); } if (action == null) { throw new ArgumentNullException("action"); } if (init == null) { throw new ArgumentNullException("init"); } if (destruct == null) { throw new ArgumentNullException("destruct"); } ParallelLoopState.ExternalInfos infos = new ParallelLoopState.ExternalInfos(); TLocal local = init(); ParallelLoopState state = new ParallelLoopState(infos); CancellationToken token = options.CancellationToken; try { var elements = enumerable(1) [0]; // 1 slice while (elements.MoveNext()) { if (infos.IsStopped || infos.IsBroken.Value) { break; } token.ThrowIfCancellationRequested(); local = action(elements.Current, state, local); } } finally { destruct(local); } return(new ParallelLoopResult(infos.LowestBreakIteration, !(infos.IsStopped || infos.IsExceptional))); }
/// <summary> /// Parallel for loop. /// </summary> /// <param name="fromInclusive">From inclusive.</param> /// <param name="toExclusive">To exclusive.</param> /// <param name="parallelOptions">Parallel options.</param> /// <param name="localInit">Local init.</param> /// <param name="body">Body.</param> /// <param name="localFinally">Local finally.</param> /// <typeparam name="TLocal">The 1st type parameter.</typeparam> public static ParallelLoopResult For <TLocal> (int fromInclusive, int toExclusive, ParallelOptions parallelOptions, Func <TLocal> localInit, Func <int, ParallelLoopState, TLocal, TLocal> body, Action <TLocal> localFinally) { if (SupportsParallelism) { return(Parallel.For(fromInclusive, toExclusive, parallelOptions, localInit, body, localFinally)); } if (body == null) { throw new ArgumentNullException("body"); } if (localInit == null) { throw new ArgumentNullException("localInit"); } if (localFinally == null) { throw new ArgumentNullException("localFinally"); } if (parallelOptions == null) { throw new ArgumentNullException("options"); } if (fromInclusive >= toExclusive) { return(new ParallelLoopResult(null, true)); } ParallelLoopState.ExternalInfos infos = new ParallelLoopState.ExternalInfos(); TLocal local = localInit(); ParallelLoopState state = new ParallelLoopState(infos); CancellationToken token = parallelOptions.CancellationToken; try { for (int i = fromInclusive; i < toExclusive; ++i) { if (infos.IsStopped) { break; } token.ThrowIfCancellationRequested(); if (infos.LowestBreakIteration != null && infos.LowestBreakIteration > i) { break; } state.CurrentIteration = i; local = body(i, state, local); } } finally { localFinally(local); } return(new ParallelLoopResult(infos.LowestBreakIteration, !(infos.IsStopped || infos.IsExceptional))); }