예제 #1
0
        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);
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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();
        }