public override IEnumerable <string> Process() { PrepareBeforeProcessing(); var result = new ConcurrentBag <string>(); var taskProcessors = GetTaskProcessors(); if (ParallelMode && taskProcessors.Count > 1) { var exceptions = new ConcurrentQueue <Exception>(); int totalCount = taskProcessors.Count; Progress.SetRange(0, totalCount); var finishedProcessors = new ConcurrentList <IParallelTaskProcessor>(); var curProcessors = new ConcurrentList <IParallelTaskProcessor>(); Progress.SetMessage("Start processing ... "); DateTime start = DateTime.Now; Parallel.ForEach(taskProcessors, Option, (processor, loopState) => { curProcessors.Add(processor); processor.LoopState = loopState; processor.Progress = Progress; try { var curResult = processor.Process(); foreach (var f in curResult) { result.Add(f); } curProcessors.Remove(processor); finishedProcessors.Add(processor); if (!Progress.IsConsole()) { Progress.SetPosition(finishedProcessors.Count); } DateTime end = DateTime.Now; var cost = end - start; var expectEnd = start.AddSeconds(cost.TotalSeconds / finishedProcessors.Count * totalCount); Progress.SetMessage("{0} threads running, {1} / {2} finished, expect to be end at {3}", curProcessors.Count, finishedProcessors.Count, totalCount, expectEnd); } catch (Exception e) { exceptions.Enqueue(e); loopState.Stop(); } GC.Collect(); }); if (Progress.IsCancellationPending()) { throw new UserTerminatedException(); } if (exceptions.Count > 0) { if (exceptions.Count == 1) { throw exceptions.First(); } else { StringBuilder sb = new StringBuilder(); foreach (var ex in exceptions) { sb.AppendLine(ex.ToString()); } throw new Exception(sb.ToString()); } } } else { for (int i = 0; i < taskProcessors.Count; i++) { if (Progress.IsCancellationPending()) { throw new UserTerminatedException(); } string rootMsg = MyConvert.Format("{0} / {1}", i + 1, taskProcessors.Count); Progress.SetMessage(1, rootMsg); var processor = taskProcessors[i]; processor.Progress = Progress; var curResult = processor.Process(); foreach (var f in curResult) { result.Add(f); } } } DoAfterProcessing(result); return(result); }
public override IEnumerable <string> Process(string aPath) { PrepareBeforeProcessing(aPath); var result = new ConcurrentBag <string>(); if (ParallelMode && _sourceFiles.Count > 1) { var exceptions = new ConcurrentQueue <Exception>(); int totalCount = _sourceFiles.Count; Progress.SetRange(0, totalCount); var curFiles = new ConcurrentList <string>(); var finishedFiles = new ConcurrentList <string>(); var curProcessors = new ConcurrentList <IParallelTaskFileProcessor>(); Parallel.ForEach(_sourceFiles, Option, (sourceFile, loopState) => { curFiles.Add(sourceFile); Progress.SetMessage("Processing {0}, finished {1} / {2}", curFiles.Count, finishedFiles.Count, totalCount); IParallelTaskFileProcessor processor = GetTaskProcessor(aPath, sourceFile); if (processor == null) { curFiles.Remove(sourceFile); finishedFiles.Add(sourceFile); return; } processor.LoopState = loopState; processor.Progress = Progress; curProcessors.Add(processor); try { var curResult = processor.Process(sourceFile); foreach (var f in curResult) { result.Add(f); } curFiles.Remove(sourceFile); finishedFiles.Add(sourceFile); Progress.SetPosition(finishedFiles.Count); Progress.SetMessage("Processing {0}, finished {1} / {2}", curFiles.Count, finishedFiles.Count, totalCount); } catch (Exception e) { exceptions.Enqueue(e); loopState.Stop(); } GC.Collect(); }); if (Progress.IsCancellationPending()) { throw new UserTerminatedException(); } if (exceptions.Count > 0) { if (exceptions.Count == 1) { throw exceptions.First(); } else { StringBuilder sb = new StringBuilder(); foreach (var ex in exceptions) { sb.AppendLine(ex.ToString()); } throw new Exception(sb.ToString()); } } } else { for (int i = 0; i < _sourceFiles.Count; i++) { if (Progress.IsCancellationPending()) { throw new UserTerminatedException(); } string rootMsg = MyConvert.Format("{0} / {1} : {2}", i + 1, _sourceFiles.Count, _sourceFiles[i]); Progress.SetMessage(1, rootMsg); IParallelTaskFileProcessor processor = GetTaskProcessor(aPath, _sourceFiles[i]); processor.Progress = Progress; var curResult = processor.Process(_sourceFiles[i]); foreach (var f in curResult) { result.Add(f); } } } DoAfterProcessing(aPath, result); return(result); }