Пример #1
0
        private static void _innerTask <TSource>(int i,
                                                 long total, DateTime started,
                                                 TSource value,
                                                 System.Func <TSource, ActionOutputData> action,
                                                 System.Action <string> logOutputFunc,
                                                 System.Action <ActionProgressData> progressOutputFunc,
                                                 string prefix, string postfix,
                                                 System.Action <Exception, TSource> onExceptionAction,
                                                 bool cancelOnError,
                                                 CancellationTokenSource cts,
                                                 ref long processedCount
                                                 )
        {
            ActionOutputData cancel = null;

            try
            {
                if (cts.IsCancellationRequested)
                {
                    return;
                }
                try
                {
                    cancel = action(value);
                    System.Threading.Interlocked.Increment(ref processedCount);
                    if (logOutputFunc != null && !string.IsNullOrEmpty(cancel.Log))
                    {
                        logOutputFunc(cancel.Log);
                    }

                    if (cancel.CancelRunning)
                    {
                        cts.Cancel();
                        return;
                    }
                }
                catch (Exception e)
                {
                    if (onExceptionAction == null)
                    {
                        onExceptionAction = (ex, val)
                                            => Devmasters.Log.Logger.Root.Error(
                            $"DoActionForAll paraller action error for {Newtonsoft.Json.JsonConvert.SerializeObject(val)}",
                            ex);
                    }
                    if (onExceptionAction != null)
                    {
                        onExceptionAction(e, value);
                    }
                    if (cancelOnError)
                    {
                        cts.Cancel();
                        return;
                    }
                }
                finally
                {
                    cancel = null;
                    if (progressOutputFunc != null)
                    {
                        ActionProgressData apd = new ActionProgressData(total, processedCount, started, prefix, postfix);
                        progressOutputFunc(apd);
                    }
                }
            }
            catch (Exception e)
            {
                if (onExceptionAction == null)
                {
                    onExceptionAction = (ex, val)
                                        => Devmasters.Log.Logger.Root.Error(
                        $"DoActionForAll paraller outside for action error for",
                        ex);
                }
                if (onExceptionAction != null)
                {
                    onExceptionAction(e, default(TSource));
                }
                if (cancelOnError)
                {
                    cts.Cancel();
                }
            }
        }
Пример #2
0
        public static void DoActionForAll <TSource, TActionParam>(
            IEnumerable <TSource> source,
            System.Func <TSource, TActionParam, ActionOutputData> action,
            TActionParam actionParameters,
            System.Action <string> logOutputFunc,
            System.Action <ActionProgressData> progressOutputFunc,
            bool parallel = true,
            int?maxDegreeOfParallelism = null,
            bool cancelOnError         = false, string prefix = null, string postfix = null, System.Action <Exception, TSource> onExceptionAction = null)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (action == null)
            {
                throw new ArgumentNullException("action");
            }

            if (prefix == null)
            {
                prefix = Devmasters.Log.StackReporter.GetCallingMethod(false, skipNamespaces: new string[] { "Devmasters.Batch" });
            }

            if (maxDegreeOfParallelism.HasValue && maxDegreeOfParallelism.Value == 1)
            {
                parallel = false;
            }

            DateTime started = DateTime.Now;

            long processedCount = 0;
            long total          = source.Count();

            bool canceled = false;

            if (parallel)
            {
                Core.logger.Debug("Starting parallel TaskManager for {count} items with prefix {prefix}", source?.Count() ?? 0, prefix);

                CancellationTokenSource cts = new CancellationTokenSource();
                try
                {
                    ParallelOptions pOptions = new ParallelOptions();
                    if (maxDegreeOfParallelism.HasValue)
                    {
                        pOptions.MaxDegreeOfParallelism = maxDegreeOfParallelism.Value;
                    }
                    pOptions.CancellationToken = cts.Token;

                    Parallel.ForEach <TSource>(source, pOptions, (value) =>
                    {
                        ActionOutputData cancel = null;
                        try
                        {
                            cancel = action(value, actionParameters);
                            System.Threading.Interlocked.Increment(ref processedCount);
                            if (logOutputFunc != null && !string.IsNullOrEmpty(cancel.Log))
                            {
                                logOutputFunc(cancel.Log);
                            }

                            if (cancel.CancelRunning)
                            {
                                cts.Cancel();
                            }
                        }
                        catch (Exception e)
                        {
                            if (onExceptionAction == null)
                            {
                                onExceptionAction = (ex, val)
                                                    => Devmasters.Log.Logger.Root.Error(
                                    $"DoActionForAll paraller action error for {Newtonsoft.Json.JsonConvert.SerializeObject(val)}",
                                    ex);
                            }
                            if (onExceptionAction != null)
                            {
                                onExceptionAction(e, value);
                            }
                            if (cancelOnError)
                            {
                                cts.Cancel();
                            }
                        }
                        finally
                        {
                            cancel = null;
                            if (progressOutputFunc != null)
                            {
                                ActionProgressData apd = new ActionProgressData(total, processedCount, started, prefix, postfix);
                                progressOutputFunc(apd);
                            }
                        }
                    });
                }
                catch (OperationCanceledException e)
                {
                    //Catestrophic Failure
                    canceled = true;
                }
            }
            else
            {
                Core.logger.Debug("Starting nonparallel TaskManager for {count} items with prefix {prefix}", source?.Count() ?? 0, prefix);
                foreach (var value in source)
                {
                    ActionOutputData cancel = action(value, actionParameters);
                    try
                    {
                        System.Threading.Interlocked.Increment(ref processedCount);

                        if (logOutputFunc != null && !string.IsNullOrEmpty(cancel.Log))
                        {
                            logOutputFunc(cancel.Log);
                        }

                        if (cancel.CancelRunning)
                        {
                            canceled = true;
                            break;
                        }
                    }
                    catch (Exception e)
                    {
                        Devmasters.Log.Logger.Root.Error("DoActionForAll action error", e);
                        if (cancelOnError)
                        {
                            break;
                        }
                    }
                    finally
                    {
                        cancel = null;
                        if (progressOutputFunc != null)
                        {
                            ActionProgressData apd = new ActionProgressData(total, processedCount, started, prefix, postfix);
                            progressOutputFunc(apd);
                        }
                    }
                }
            }
        }