private async Task Mirror(IFileSystem origin, IFileSystem destination, string path, MirrorWay way) { int numWorkers = options.Multithreaded ? options.NumWorkers : 1; var wq = new WorkQueuer("SmartCopy_Operation", numWorkers, false); if (options.UseHashList) { HashList = await SmartCopy.GetHashList(destination, way == MirrorWay.Down); } workedFiles = 0; var files = await EnumerateFilesForMirroring(origin, destination, path, way); foreach (var f in files) { wq.Enqueue(async() => { await Task.Yield(); OnFileStaged?.Invoke(f.RelativePath); if (f.Changed) { switch (way) { case MirrorWay.Up: await processFileUp(origin, destination, f.RelativePath); break; case MirrorWay.Down: await processFileDown(origin, destination, f.RelativePath); break; } } OnReportProcessedFile?.Invoke(f.Changed, f.RelativePath); }, async x => { await Task.Yield(); OnFileCopyException?.Invoke(f.RelativePath, x); }); } if (options.AllowDelete) { int DeleteLimit = 15; destination.ForFilesIn(path, (f) => { if (DeleteLimit < 1) { return; } if (Excludes.Any(x => CheckMatch(f, x))) { return; } if (!origin.Exists(f)) { if (DeleteLimit-- > 0) { destination.Delete(f); return; } } }); } wq.Start(); await wq.Stop(true); if (Debugger.IsAttached) { Debugger.Break(); } await SaveHashList(origin, destination); }
private async Task <List <CopyMirrorFileData> > EnumerateFilesForMirroring(IFileSystem origin, IFileSystem destination, string path, MirrorWay way) { List <CopyMirrorFileData> retv = new List <CopyMirrorFileData>(); foreach (var f in origin.GetFilesIn(path)) { if (f == HASHLIST_FILENAME) { continue; } if (Excludes.Any(excl => CheckMatch(f, excl))) { continue; } try { OnFileStaged?.Invoke(f); } catch (Exception x) { continue; } var changed = CopyDecisionCriteria != null ? await CopyDecisionCriteria(f) : await Changed(origin, destination, f); retv.Add(new CopyMirrorFileData { RelativePath = f, Changed = changed }); } if (options.Recursive) { foreach (var dir in origin.GetDirectoriesIn(path)) { destination.MkDirs(dir); retv.AddRange(await EnumerateFilesForMirroring(origin, destination, dir, way)); } } return(retv); }