Exemple #1
0
                protected override async Task StartPrivateAsync()
                {
                    Status = NetworkStatus.Networking;
                    try
                    {
                        OnTotalFoldersRemainChanged(1);
                        OnMessageAppended("Creating folder...");
                        var folderCreator = new RestRequests.FileCreator(cloudFolder.Id, folderName, true);
                        var eventHandler  = new MessageAppendedEventHandler((log) => { OnMessageAppended($"[Rest]{log}"); });
                        folderCreator.MessageAppended += eventHandler;
                        await folderCreator.Start();

                        folderCreator.MessageAppended -= eventHandler;
                        switch (folderCreator.Status)
                        {
                        case RestRequests.FileCreator.FileCreatorStatus.Completed:
                        {
                            CreatedCloudFolder = new CloudFile(folderCreator.Result, folderName, true, cloudFolder);
                            //CreatedCloudFolder = await cloudFolder.CreateFolderAsync(folderName);
                            OnMessageAppended("Folder created");
                            Status = NetworkStatus.Completed;
                            return;
                        }

                        case RestRequests.FileCreator.FileCreatorStatus.ErrorNeedRestart:
                        {
                            Status = NetworkStatus.ErrorNeedRestart;
                            return;
                        }

                        default:
                        {
                            throw new Exception($"Status: {Status}");
                        }
                        }
                    }
                    catch (Exception error)
                    {
                        OnMessageAppended(error.ToString());
                        Status = NetworkStatus.ErrorNeedRestart;
                        return;
                    }
                    finally
                    {
                        OnTotalFoldersRemainChanged(-1);
                    }
                }
                protected override async Task StartPrivateAsync()
                {
                    try
                    {
                        OnTotalFilesRemainChanged(1);
                        switch (Status)
                        {
                        case NetworkStatus.ErrorNeedRestart:
                        case NetworkStatus.NotStarted:
                        case NetworkStatus.Paused:
                        {
                            if (Status != NetworkStatus.Paused)
                            {
                                //Status = NetworkStatus.Starting;
                                //MyLogger.Assert(downloader == null && windowsFile == null && fileStream == null);
                                if (fileStream != null)
                                {
                                    fileStream.Dispose();
                                    fileStream = null;
                                }
                                fileStream = await windowsFile.OpenStreamForReadAsync();

                                uploader = new RestRequests.Uploader(new List <string> {
                                        CloudFolder.Id
                                    }, fileStream, fileName);
                            }
                            Status = NetworkStatus.Networking;
                            var progressChangedEventHandler = new RestRequests.ProgressChangedEventHandler((bytesProcessed, totalLength) =>
                                {
                                    BytesUploaded   = bytesProcessed;
                                    TotalFileLength = totalLength;
                                    MyLogger.Assert(this.GetType() == typeof(Uploaders.FileUploader));
                                    OnProgressChanged(BytesUploaded, TotalFileLength);
                                });
                            var messageAppendedEventHandler = new MessageAppendedEventHandler((msg) =>
                                {
                                    OnMessageAppended($"[Rest]{msg}");
                                });
                            var chunkSentEventHandler = new RestRequests.ChunkSentEventHandler((coda) =>
                                {
                                    OnChunkSent(coda);
                                });
                            int timeToWait = 500;
                            uploadAgain_index :;
                            uploader.ProgressChanged += progressChangedEventHandler;
                            uploader.MessageAppended += messageAppendedEventHandler;
                            uploader.ChunkSent       += chunkSentEventHandler;
                            await uploader.UploadAsync();

                            uploader.ProgressChanged -= progressChangedEventHandler;
                            uploader.MessageAppended -= messageAppendedEventHandler;
                            uploader.ChunkSent       -= chunkSentEventHandler;
                            switch (uploader.Status)
                            {
                            case RestRequests.Uploader.UploadStatus.Completed:
                            {
                                UploadedCloudFile = new CloudFile(uploader.CloudFileId, fileName, false, CloudFolder);
                                Status            = NetworkStatus.Completed;
                                return;
                            }

                            case RestRequests.Uploader.UploadStatus.ErrorNeedRestart:
                            {
                                OnMessageAppended("Error need restart");
                                Status = NetworkStatus.ErrorNeedRestart;
                                return;
                            }

                            case RestRequests.Uploader.UploadStatus.ErrorNeedResume:
                            {
                                if (timeToWait > Constants.MaxTimeToWait)
                                {
                                    Status = NetworkStatus.ErrorNeedRestart;
                                    return;
                                }
                                OnMessageAppended($"Error need resume... Waiting for {timeToWait} minisecs...");
                                await Task.Delay(timeToWait);

                                timeToWait *= 2;
                                goto uploadAgain_index;
                            }

                            case RestRequests.Uploader.UploadStatus.Paused:
                            {
                                Status = NetworkStatus.Paused;
                                return;
                            }

                            case RestRequests.Uploader.UploadStatus.Uploading:
                            case RestRequests.Uploader.UploadStatus.NotStarted:
                            default: throw new Exception($"uploader.Status: {uploader.Status}");
                            }
                        }

                        case NetworkStatus.Completed:
                        case NetworkStatus.Networking:
                            //case NetworkStatus.Starting:
                        {
                            OnMessageAppended($"Status: {Status}, no way to start");
                            return;
                        }

                        default: throw new Exception($"Status: {Status}");
                        }
                    }
                    catch (Exception error)
                    {
                        OnMessageAppended($"[Unexpected]{error}");
                        Status = NetworkStatus.ErrorNeedRestart;
                    }
                    finally
                    {
                        OnTotalFilesRemainChanged(-1);
                    }
                }
                protected override async Task StartPrivateAsync()
                {
                    switch (Status)
                    {
                    case NetworkStatus.ErrorNeedRestart:
                    case NetworkStatus.NotStarted:
                    case NetworkStatus.Paused:
                    {
                        if (Status != NetworkStatus.Paused)
                        {
                            //Status = NetworkStatus.Starting;
                            //MyLogger.Assert(downloader == null && windowsFile == null && fileStream == null);
                            windowsFile = await CreateTemporaryFile();

                            fileStream = await windowsFile.OpenStreamForWriteAsync();

                            downloader = new RestRequests.Downloader(CloudFile.Id, fileStream);
                        }
                        Status = NetworkStatus.Networking;
                        var progressChangedEventHandler = new RestRequests.ProgressChangedEventHandler((bytesProcessed, totalLength) =>
                            {
                                BytesDownloaded = bytesProcessed;
                                TotalFileLength = totalLength;
                                MyLogger.Assert(this.GetType() == typeof(Downloaders.FileDownloader));
                                OnProgressChanged(BytesDownloaded, TotalFileLength);
                            });
                        var messageAppendedEventHandler = new MessageAppendedEventHandler((msg) =>
                            {
                                OnMessageAppended("Rest: " + msg);
                            });
                        downloader.ProgressChanged += progressChangedEventHandler;
                        downloader.MessageAppended += messageAppendedEventHandler;
                        await downloader.DownloadAsync();

                        downloader.ProgressChanged -= progressChangedEventHandler;
                        downloader.MessageAppended -= messageAppendedEventHandler;
                        downloadAgain_index :;
                        switch (downloader.Status)
                        {
                        case RestRequests.Downloader.DownloadStatus.Completed :
                            {
                                fileStream.Dispose();
                                Status = NetworkStatus.Completed;
                                return;
                            }

                        case RestRequests.Downloader.DownloadStatus.ErrorNeedRestart:
                        {
                            OnMessageAppended("Error need restart");
                            Status = NetworkStatus.ErrorNeedRestart;
                            return;
                        }

                        case RestRequests.Downloader.DownloadStatus.ErrorNeedResume:
                        {
                            OnMessageAppended("Error need resume...");
                            goto downloadAgain_index;
                        }

                        case RestRequests.Downloader.DownloadStatus.Paused:
                        {
                            Status = NetworkStatus.Paused;
                            return;
                        }

                        case RestRequests.Downloader.DownloadStatus.Downloading:
                        case RestRequests.Downloader.DownloadStatus.NotStarted:
                        default: throw new Exception($"downloader.Status: {downloader.Status}");
                        }
                    }

                    case NetworkStatus.Completed:
                    case NetworkStatus.Networking:
                    //case NetworkStatus.Starting:
                    default: throw new Exception($"Status: {Status}");
                    }
                }
                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();
                    }
                }