private async Task RunUploadsAsync(bool wait) { IsWorking = true; try { CancellationDisposable cancellation = new CancellationDisposable(); _runningUpload.Disposable = cancellation; HashSet <string> paths = new HashSet <string>(); if (_queue.Uploads.Any() && wait) { await Task.Delay(WaitTimeBeforeUpload, cancellation.Token); } Upload upload = null; while (cancellation.Token.IsCancellationRequested == false && _queue.TryPeek(out upload) && upload != null && paths.Contains(upload.Recording.Path) == false) { CurrentUpload = upload; paths.Add(upload.Recording.Path); try { var progress = new Progress <UploadStatus>(upload.UpdateStatus); using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellation.Token)) { await UploadRecordingDataAsync(upload.Recording, progress, cts.Token); } } catch (Exception ex) { // log } // TODO what if failed? _queue.TryDequeue(out upload); if (upload.Status.Step != UploadStep.Completed) { _queue.TryEnqueue(upload.Recording); await Task.Delay(_timeoutStepper.Current, cancellation.Token); _timeoutStepper.MoveNext(); } else { _timeoutStepper.Reset(); } } ResetUpload(); } catch (OperationCanceledException) { } finally { IsWorking = false; } }