protected override async Task StartPrivateAsync() { ReleaseSemaphoreSlim(); try { switch (Status) { case NetworkStatus.NotStarted: { Status = NetworkStatus.Networking; if (UploadedCloudFolder == null) { var fc = new Modifiers.FolderCreator(cloudFolder, this.windowsFolder.Name); var messageAppendedEventHandler = new MessageAppendedEventHandler((msg) => { OnMessageAppended($"[FC]{msg}"); }); OnMessageAppended("Creating folder..."); fc.MessageAppended += messageAppendedEventHandler; await fc.StartUntilCompletedAsync(); fc.MessageAppended -= messageAppendedEventHandler; //switch (fc.Status) //{ // case NetworkStatus.Completed: // { OnMessageAppended("Folder created"); UploadedCloudFolder = fc.CreatedCloudFolder; OnProgressChanged(0, 0); } //NetworkingCount--; var windowsFiles = await this.windowsFolder.GetFilesAsync(); lock (subTasks) { foreach (var f in windowsFiles) { subTasks.Add(new FileUploader(UploadedCloudFolder, f, f.Name)); } } var windowsFolders = await this.windowsFolder.GetFoldersAsync(); lock (subTasks) { foreach (var f in windowsFolders) { var folderUploader = new FolderUploader(UploadedCloudFolder, f); subTasks.Add(folderUploader); } } long currentProgress = 1, totalProgress = windowsFiles.Count + 1; OnProgressChanged(currentProgress, totalProgress); CurrentProgressChanged?.Invoke(1); TotalProgressChanged?.Invoke(windowsFiles.Count + 1); Func <Networker, Task> action; if (Status == NetworkStatus.Paused) { action = new Func <Networker, Task>(async(st) => { await st.WaitUntilCompletedAsync(); }); } else { action = new Func <Networker, Task>(async(st) => { await st.StartUntilCompletedAsync(); }); } IEnumerable <Task> tasks; lock (subTasks) { var currentProgressChangedEventHandler = new TotalProgressChangedEventHandler((dif) => { MyLogger.Assert(dif == 1); CurrentProgressChanged?.Invoke(dif); OnProgressChanged(currentProgress += dif, totalProgress); }); var totalProgressChangedEventHandler = new TotalProgressChangedEventHandler((dif) => { TotalProgressChanged?.Invoke(dif); OnProgressChanged(currentProgress, totalProgress += dif); }); tasks = subTasks.ToList().Select(async(st) => { if (st.GetType() == typeof(CloudFile.Uploaders.FolderUploader)) { var fu = st as CloudFile.Uploaders.FolderUploader; fu.CurrentProgressChanged += currentProgressChangedEventHandler; fu.TotalProgressChanged += totalProgressChangedEventHandler; await action(st); fu.CurrentProgressChanged -= currentProgressChangedEventHandler; fu.TotalProgressChanged -= totalProgressChangedEventHandler; } else { await action(st); CurrentProgressChanged?.Invoke(1); OnProgressChanged(++currentProgress, totalProgress); } }); } await Task.WhenAll(tasks); //NetworkingCount++; Status = NetworkStatus.Completed; return; // } // case NetworkStatus.ErrorNeedRestart: // { // this.Status = NetworkStatus.ErrorNeedRestart; // return; // } // default: throw new Exception($"Status: {Status}"); //} } case NetworkStatus.Paused: { Status = NetworkStatus.Networking; await Task.WhenAll(subTasks.ToList().Select(async(st) => { await st.StartAsync(); })); //Status = NetworkStatus.Completed; } break; default: { OnMessageAppended($"Status: {Status}, no way to start"); } break; } } catch (Exception error) { throw error; } finally { await WaitSemaphoreSlimAsync(); } }
private async Task <NetworkStatus> VerifyFolder() { Status = NetworkStatus.Networking; long currentProgress = 0, totalProgress = 1; OnProgressChanged(currentProgress, totalProgress); if (cloudFolder.Name != windowsFolder.Name) { OnMessageAppended($"Name not consistent, Cloud: {cloudFolder.Name}, Local: {windowsFolder.Name}"); return(NetworkStatus.ErrorNeedRestart); } var folderVerifiers = new List <Tuple <CloudFile, Windows.Storage.StorageFolder> >(); { if (!await GetCloudSubFolders()) { return(NetworkStatus.ErrorNeedRestart); } Dictionary <string, Windows.Storage.StorageFolder> localSubFolders = new Dictionary <string, Windows.Storage.StorageFolder>(); foreach (var f in await windowsFolder.GetFoldersAsync()) { if (!cloudSubFolders.ContainsKey(f.Name)) { OnMessageAppended($"Cloud Folder doesn't exist: {f.Name}"); return(NetworkStatus.ErrorNeedRestart); } localSubFolders.Add(f.Name, f); } foreach (var p in cloudSubFolders) { if (!localSubFolders.ContainsKey(p.Key)) { OnMessageAppended($"Local Folder doesn't exist: {p.Key}"); return(NetworkStatus.ErrorNeedRestart); } folderVerifiers.Add(new Tuple <CloudFile, Windows.Storage.StorageFolder>(p.Value, localSubFolders[p.Key])); localSubFolders.Remove(p.Key); } MyLogger.Assert(localSubFolders.Count == 0); } { if (!await GetCloudSubFiles()) { return(NetworkStatus.ErrorNeedRestart); } Dictionary <string, Windows.Storage.StorageFile> localSubFiles = new Dictionary <string, Windows.Storage.StorageFile>(); foreach (var f in await windowsFolder.GetFilesAsync()) { if (!cloudSubFiles.ContainsKey(f.Name)) { OnMessageAppended($"Cloud File doesn't exist: {f.Name}"); return(NetworkStatus.ErrorNeedRestart); } localSubFiles.Add(f.Name, f); } foreach (var p in cloudSubFiles) { if (!localSubFiles.ContainsKey(p.Key)) { OnMessageAppended($"Local File doesn't exist: {p.Key}"); return(NetworkStatus.ErrorNeedRestart); } } OnProgressChanged(++currentProgress, totalProgress += cloudSubFiles.Count); CurrentProgressChanged?.Invoke(1); TotalProgressChanged?.Invoke(cloudSubFiles.Count); OnMessageAppended("Verifying subfiles..."); int filesVerified = 0; foreach (var p in cloudSubFiles) { var localFile = localSubFiles[p.Key]; var stream = await localFile.OpenStreamForReadAsync(); var localMd5 = await Libraries.GetSha256ForWindowsStorageFile(stream); stream.Dispose(); if (localMd5 != p.Value || p.Value == null) { OnMessageAppended($"{p.Key} content not consistent, Cloud: {p.Value}, Local: {localMd5}"); CurrentProgressChanged?.Invoke(-filesVerified - 1); TotalProgressChanged?.Invoke(-cloudSubFiles.Count); return(NetworkStatus.ErrorNeedRestart); } OnProgressChanged(++currentProgress, totalProgress); CurrentProgressChanged?.Invoke(1); ++filesVerified; localSubFiles.Remove(p.Key); } OnMessageAppended("Subfiles verified."); MyLogger.Assert(localSubFiles.Count == 0); } OnProgressChanged(currentProgress, totalProgress += folderVerifiers.Count); TotalProgressChanged?.Invoke(folderVerifiers.Count); ReleaseSemaphoreSlim(); OnMessageAppended("Waiting for subfolders to be verified..."); try { await Task.WhenAll(folderVerifiers.Select(async(tuple) => { var totalProgressChangedEventHandler = new TotalProgressChangedEventHandler((difference) => { OnProgressChanged(currentProgress, totalProgress += difference); TotalProgressChanged?.Invoke(difference); }); var currentProgressChangedEventHandler = new TotalProgressChangedEventHandler((difference) => { //MyLogger.Assert(difference == 1); OnProgressChanged(currentProgress += difference, totalProgress); CurrentProgressChanged?.Invoke(difference); }); var verifier = new Verifiers.FolderVerifier(tuple.Item1, tuple.Item2); verifier.TotalProgressChanged += totalProgressChangedEventHandler; verifier.CurrentProgressChanged += currentProgressChangedEventHandler; await verifier.StartUntilCompletedAsync(); verifier.TotalProgressChanged -= totalProgressChangedEventHandler; verifier.CurrentProgressChanged -= currentProgressChangedEventHandler; })); return(NetworkStatus.Completed); } finally { await WaitSemaphoreSlimAsync(); } }