如何从任务内取消parallel.foreach循环

时间:2016-03-04 12:49:30

标签: c# foreach parallel-processing

我有一个ImageProcessor类,为每个图像提供程序创建一个任务列表,在这些任务中我然后为每个提供程序的所有图像运行parallel.foreach循环,我希望能够取消所有来自控制台的任务和嵌套并行循环,我已经找到了如何取消任务以及如何取消并行循环的示例,但我不确定如何对嵌套进程执行此操作。

以下是我目前的代码

从我的控制台应用中:

using (IUnityContainer container = Bootstrapper.Initialise())
            {
                IImageProcessor processor = container.Resolve<IImageProcessor>();

                processor.Container = container;

                try
                {
                    InputArguments arguments = new InputArguments(args);

                    if (arguments.Contains("fs"))
                    {
                        processor.Initialise(arguments["fs"]);
                    }
                    else
                    {
                        processor.Initialise();
                    }

                    processor.Run();

                    Console.WriteLine("\r\n\n\nPress any key to Exit");
                    Console.ReadLine();

                    return (int)ExitCode.Success;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);

                    Console.WriteLine("\r\n\n\nPress any key to Exit");
                    Console.ReadLine();

                    return (int)ExitCode.UnknownError;
                }
            }

运行方法

public void Run()
        {
            List<Task> tasks = new List<Task>();

            foreach (IFileService fileservice in this.fileServices)
            {
                Task task = Task.Factory.StartNew((arg) =>
                {
                    IFileService fs = (IFileService)arg;

                    string msg = $"Processing {fs.ToString()}...";

                    FileLogger.Write(msg, fs.ToString());
                    ConsoleLogger.WriteLine(msg);
                    fs.ProcessFiles();
                    //fileservice.ReprocessUnMatchedData();
                }, fileservice);

                tasks.Add(task);
            }

            Task.WaitAll(tasks.ToArray());
        }

在每个文件服务中我都调用了这个方法:

protected bool ProcessFileRecord<T>() where T : IDataRecord
        {
            int matched = 0;
            int notMatched = 0;
            int skipped = 0;
            bool result;
            object lockObject = new object();

            try
            {
                processTracker = GetTracker();

                if (databaseHelper.TrackerFullyProcessed(processTracker))
                {
                    LoggingService.Write("File already processed... Skipping.", LoggingTarget.All, serviceName);

                    result = true;
                }

                LoggingService.Write($"\r\nProcessing index file {fileRecord.IndexFileName}", LoggingTarget.File, serviceName);

                Parallel.ForEach(
                    fileRecord.DataRecords,
                    new ParallelOptions() { MaxDegreeOfParallelism = Thread.CurrentThread.ManagedThreadId },
                    (item) =>
                    {
                        switch ((RecordProcessResult)ProcessRecord(item))
                        {
                            case RecordProcessResult.Invalid:
                                break;

                            case RecordProcessResult.Matched:
                                Increment(ref matched);
                                break;

                            case RecordProcessResult.NotMatched:
                                Increment(ref notMatched);
                                break;

                            case RecordProcessResult.Skipped:
                                Increment(ref skipped);
                                break;

                            default:
                                break;
                        }

                        lock (lockObject)
                        {
                            if ((matched + notMatched + skipped) % 100 == 0)
                            {
                                LoggingService.Write($"\tMatched: {matched}\tNot Matched: {notMatched}\tSkipped: {skipped}\t total: {matched + notMatched + skipped}", LoggingTarget.Trace & LoggingTarget.Console, serviceName);
                            }
                        }
                    });

                LoggingService.Write($"Total Lines: {matched + notMatched + skipped} \r\nMatched: {matched} \r\nNot Matched: {notMatched} \r\nSkipped: {skipped}", LoggingTarget.All, serviceName);

                this.databaseHelper.UpdateTracker(this.processTracker, matched, notMatched);

                result = true;
            }
            catch (Exception ex)
            {
                LoggingService.Write($"Error processing data file:{fileRecord.IndexFileName}", LoggingTarget.All, serviceName);

                LoggingService.Write($"{ex.ExceptionTreeAsString()}", LoggingTarget.All, serviceName);

                LoggingService.Write($"Total Lines: {(matched + notMatched + skipped)} \r\nMatched: {matched} \r\nNot Matched: {notMatched} \r\nSkipped: {skipped}", LoggingTarget.All, serviceName);

                this.databaseHelper.UpdateTracker(this.processTracker, matched, notMatched);

                result = false;
            }

            return result;
        }

感谢。

1 个答案:

答案 0 :(得分:0)

请在此页面上查看示例 CancellationTokenSource