/// <summary> /// 通过指定的 MassCompressOption 实例执行批量文件压缩 /// </summary> /// <param name="sourceDirectory">源文件夹</param> /// <param name="option"></param> public static void CompressMultiple(string sourceDirectory, string outputPath, IMassCompressOption option) { var list = DirectoryAnalyst.GetImageFilesList(sourceDirectory, !option.NoRecurse); if (option.NoKeepStruct) { CompressMultiple(list, outputPath, option); } //分组目录结构 var query = from file in list //分组的Key ::: -文件所在目录 与 源目录 的相对路径 相对于 输出目录 即 最终输出文件应在的目录 group file by Path.GetFullPath(Path.GetRelativePath(sourceDirectory, Path.GetDirectoryName(file)), outputPath) into fileGroup //orderby fileGroup.Key select fileGroup; var queue = new Queue <Exception>(); foreach (var i in query) { try { CompressMultiple(i, i.Key, option); } catch (AggregateException e) { foreach (var item in e.InnerExceptions) { queue.Enqueue(item); } } } if (queue.Count > 0) { throw new AggregateException(queue); } }
/// <summary> /// 通过指定的 MassCompressOption 实例执行批量文件压缩 /// </summary> /// <exception cref="AggregateException"></exception> public static void CompressMultiple(IEnumerable <string> files, string outputPath, IMassCompressOption option) { if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } // Use ConcurrentQueue to enable safe enqueueing from multiple threads. var exceptions = new System.Collections.Concurrent.ConcurrentQueue <Exception>(); // Execute the complete loop and capture all exceptions. Parallel.ForEach(files, file => { try { CompressSingle(file, outputPath, option); } // Store the exception and continue with the loop. catch (Exception e) { e.Source = file; exceptions.Enqueue(e); } }); // Throw the exceptions here after the loop completes. if (exceptions.Count > 0) { throw new AggregateException(exceptions); } }