Пример #1
0
        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)));
        }
Пример #2
0
        /// <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)));
        }