简体   繁体   English

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

[英]how to cancel parallel.foreach loop from inside a task

I have a ImageProcessor class that creates a list of tasks for each of the image providers, inside of these tasks I then run a parallel.foreach loop for all the images for each provider, I want to be able to cancel all the tasks and nested parallel loops from the console, I've found example of how to cancel tasks and how to cancel parallel loops, but I am unsure as how to do it for nested processes. 我有一个ImageProcessor类,它为每个图像提供程序创建一个任务列表,然后在这些任务中,为每个提供程序的所有图像运行一个parallel.foreach循环,我希望能够取消所有任务并嵌套从控制台的并行循环中,我找到了有关如何取消任务以及如何取消并行循环的示例,但是我不确定如何对嵌套进程执行此操作。

Below is the code I have at the moment 下面是我目前的代码

From my console app: 从我的控制台应用程序:

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;
                }
            }

The Run method 运行方法

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());
        }

and inside each file service I have call this method: 在每个文件服务中,我都调用了此方法:

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;
        }

Thank. 谢谢。

请在此页面上查看示例CancellationTokenSource

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM