using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using CatalogVbLib; using Dasync.Collections; namespace MaddoShared { public class ImageCreationStuff { public class Options { public bool AggiornaSottodirectory { get; set; } public bool CreaSottocartelle { get; set; } public int FilePerCartella { get; set; } public string SuffissoCartelle { get; set; } public int CifreContatore { get; set; } public NumerazioneType NumerazioneType { get; set; } public string SourcePath { get; set; } public string DestinationPath { get; set; } public int MaxThreads { get; set; } public int ChunksSize { get; set; } public bool LinearExecution { get; set; } } public async Task CreaCatalogoParallel(Options options, ConcurrentBag results, EventHandler> updateEvent, CancellationToken cancellationToken = default(CancellationToken)) { var stopwatch = new Stopwatch(); stopwatch.Start(); // todo immagini counter //todo set label await CreaImmaginiParallel(options, results, updateEvent, cancellationToken); // todo set finito label stopwatch.Stop(); return $"{stopwatch.Elapsed.Hours}h {stopwatch.Elapsed.Minutes}m ${stopwatch.Elapsed.Seconds}s ({stopwatch.Elapsed.TotalSeconds}s)"; } public async Task CreaImmaginiParallel(Options options, ConcurrentBag results, EventHandler> updateEvent, CancellationToken cancellationToken = default(CancellationToken)) { var dataToProcess = new List(); if (options.AggiornaSottodirectory && options.CreaSottocartelle) { var helper = new FileHelperSharp(); dataToProcess = helper.GetFilesRecursive(new DirectoryInfo(options.SourcePath), new DirectoryInfo(options.DestinationPath), "*.jpg", new FileHelperOptions() { FilesPerFolder = options.FilePerCartella, Suffix = options.SuffissoCartelle, CounterSize = options.CifreContatore, NumerationType = options.NumerazioneType }); } else if (!options.CreaSottocartelle) { var files = Directory.EnumerateFiles(options.SourcePath, "*.jpg", options.AggiornaSottodirectory ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); dataToProcess = files.Select(x => { var fInfo = new FileInfo(x); var filePath = fInfo.DirectoryName; var trimmedSourcePath = options.SourcePath.TrimEnd('\\'); var newFilePath = fInfo.FullName.Replace(trimmedSourcePath, "").TrimStart('\\'); newFilePath = Path.Combine(options.DestinationPath, newFilePath); var destFolderPath = new FileInfo(newFilePath).DirectoryName; var destFolderInfo = new DirectoryInfo(destFolderPath); destFolderInfo.EnsureDirectoryExists(); return new FileData(fInfo, new DirectoryInfo(new FileInfo(newFilePath).DirectoryName)); }).ToList(); //// TODO //dataToProcess = // (from f in Directory.EnumerateFiles(options.SourcePath, "*.jpg", // options.AggiornaSottodirectory // ? SearchOption.AllDirectories // : SearchOption.TopDirectoryOnly) // select new FileData(new FileInfo(f), // new DirectoryInfo(options.DestinationPath.PathCombine( // new FileInfo(f).DirectoryName.Replace(options.SourcePath.TrimEnd(new char[] {'\\'}), "") // ) // ) // ) // ) // .ToList(); } var threads = options.MaxThreads == 0 ? Environment.ProcessorCount * 2 : options.MaxThreads; var scheduler = new ConcurrentExclusiveSchedulerPair(TaskScheduler.Default, threads) .ConcurrentScheduler; //var allTasks = new List(); var test = from d in dataToProcess select Task.Factory.StartNew(async () => { await new ImageCreatorSharp(d.File, d.Directory).CreaImmagineThread(d.File.Name); //var imgC = new ImageCreatorSharp(d.File, d.Directory); //imgC.CreaImmagineThread(d.File.Name); //imgC = null; }, CancellationToken.None, TaskCreationOptions.None, scheduler); //int count = 0; if (options.LinearExecution) { foreach (var task in test) { await task; } } else { if (options.ChunksSize == 0) { //var opts = new ParallelOptions() { MaxDegreeOfParallelism = threads, CancellationToken = cancellationToken, TaskScheduler = scheduler}; await dataToProcess.ParallelForEachAsync(async fileData => { await new ImageCreatorSharp(fileData.File, fileData.Directory).CreaImmagineThread(fileData.File.Name); results.Add(fileData.File.Name); //count = Interlocked.Increment(ref count); try { updateEvent?.Invoke(this, new Tuple(fileData.File.Name, dataToProcess.Count) ); } catch (Exception e) { Console.WriteLine(e); throw; } }, maxDegreeOfParallelism: threads, false, cancellationToken); } else { var asdf = SplitList(dataToProcess.ToList(), options.ChunksSize).ToList(); foreach (var sdaf in asdf) { await sdaf.ParallelForEachAsync(async fileData => { await new ImageCreatorSharp(fileData.File, fileData.Directory).CreaImmagineThread(fileData.File.Name); results.Add(fileData.File.Name); //count = Interlocked.Increment(ref count); try { updateEvent?.Invoke(this, new Tuple(fileData.File.Name, dataToProcess.Count)); } catch (Exception e) { Console.WriteLine(e); throw; } }, maxDegreeOfParallelism: threads, false, cancellationToken); } } } } public static IEnumerable> SplitList(List bigList, int nSize = 3) { for (int i = 0; i < bigList.Count; i += nSize) { yield return bigList.GetRange(i, Math.Min(nSize, bigList.Count - i)); } } } }