public IDownload DownloadFile(string url, string assetFilename = null) { Tuple <IDisposable, IDownload> currentDownload; if (CurrentDownloadDictionary.TryGetValue(url, out currentDownload)) { return(currentDownload.Item2); } if (assetFilename != null) { var duplicateFile = DownloadQueue.FirstOrDefault(x => x.FileIdentifier == assetFilename); if (duplicateFile != null) { return(duplicateFile); } } Download download = new Download(url, assetFilename ?? Guid.NewGuid().ToString()); download.Status = DownloadStatus.Queued; Debug.WriteLine($"Enqueue: {download.FileIdentifier}"); DownloadQueue.Enqueue(download); _downloadUpdateSubject.OnNext(download); StartQueue(); return(download); }
public void CancelDownload(string url) { Tuple <IDisposable, IDownload> currentDownload; if (CurrentDownloadDictionary.TryGetValue(url, out currentDownload)) { currentDownload.Item1.Dispose(); } var downloads = _downloads.Where(x => x.Url == url).ToList(); foreach (var download in downloads) { ((Download)download).Status = DownloadStatus.Cancelled; _downloads.Remove(download); } }
public void ProcessQueue() { if (_downloads.Count >= NumberOfConcurrentDownloads) { return; } IDownload outDownload; if (!DownloadQueue.TryDequeue(out outDownload)) { return; } Debug.WriteLine($"Deque: {outDownload.FileIdentifier}"); // If the download has been cancelled we skip it if (outDownload.Status == DownloadStatus.Cancelled) { return; } var download = (Download)outDownload; _downloads.Add(outDownload); download.Status = DownloadStatus.InProgress; Debug.WriteLine($"Download Start: {download.FileIdentifier}"); TaskCompletionSource <bool> taskCompletionSource = new TaskCompletionSource <bool>(); IObservable <double> downloadFileObservable = HttpService.DownloadFileAsync(download.Url, download.FileIdentifier, _storage.GetOutputStream(download.FileIdentifier)); IDisposable disposable = downloadFileObservable.Subscribe(d => { download.ProgressSubject.OnNext(d); }, exception => { Debug.WriteLine($"Download Error: {download.FileIdentifier}"); download.ErrorCount++; if (download.ErrorCount >= 3) { Debug.WriteLine($"Download Error Remove: {download.FileIdentifier}"); download.Status = DownloadStatus.Failed; _downloadUpdateSubject.OnNext(download); download.ProgressSubject.OnError(exception); _progressSubject.OnNext(DownloadQueue.Count + CurrentDownloadDictionary.Count); } else { Debug.WriteLine($"Download Error Qeueu: {download.FileIdentifier}"); // Download failed so we add it to queue again download.Status = DownloadStatus.Queued; _downloadUpdateSubject.OnNext(download); DownloadQueue.Enqueue(download); } Tuple <IDisposable, IDownload> compeltedDownload; CurrentDownloadDictionary.TryRemove(download.Url, out compeltedDownload); _downloads.Remove(download); StartQueue(); }, () => { Debug.WriteLine($"Download Complete: {download.FileIdentifier}"); _downloads.Remove(download); download.Status = DownloadStatus.Complete; _downloadUpdateSubject.OnNext(download); taskCompletionSource.TrySetResult(true); download.ProgressSubject.OnCompleted(); Tuple <IDisposable, IDownload> compeltedDownload; CurrentDownloadDictionary.TryRemove(download.Url, out compeltedDownload); _progressSubject.OnNext(DownloadQueue.Count + CurrentDownloadDictionary.Count); StartQueue(); }); if (!CurrentDownloadDictionary.TryAdd(download.Url, new Tuple <IDisposable, IDownload>(disposable, download))) { throw new Exception("Could not add download to dictionary"); } //while (Downloads.Count(x => x.Status == DownloadStatus.InProgress) >= NumberOfConcurrentDownloads) { // Debug.WriteLine("Start wait"); // await taskCompletionSource.Task; // Debug.WriteLine("End wait"); //} StartQueue(); }