Пример #1
0
        private void Thread_Failed(object sender, ThreadExitedArgs e)
        {
            bool isRaiseFailed = false;

            lock (this._syncRoot)
            {
                if (e.WorkID != this._workID)
                {
                    return;                          // 这次操作已经过期
                }
                if (this._status != DownloaderStatuses.Downloading)
                {
                    return;                                                // 只有Downloading状态才可能变为Failed状态
                }
                this.RefreshWorkID();
                this._status = DownloaderStatuses.Failed;
                this._progressTimer.Dispose();
                this._progressTimer = null;
                this.ClearThread();
                this.CacheConfig();// 保存文件配置以便以后继续下载
                this._sourceProvider = null;
                this._writer.Dispose();
                this._writer = null;

                isRaiseFailed = true;
            }// lock

            if (isRaiseFailed)
            {
                this.OnFailed();
            }
        }
Пример #2
0
        /// <summary>
        /// 暂停,可以调用Start继续下载
        /// </summary>
        public void Pause()
        {
            lock (this._syncRoot)
            {
                if (this._status != DownloaderStatuses.Downloading)
                {
                    return;
                }

                this._status = DownloaderStatuses.Paused;
                // 刷新WorkID
                this.RefreshWorkID();
                this._progressTimer.Dispose();
                this._progressTimer = null;
                this.ClearThread();
                // 缓存配置文件
                this.CacheConfig();
                // 清空SourceProvider
                this._sourceProvider = null;
                // 释放Writer
                this._writer.Dispose();
                this._writer = null;
            }// lock

            this.OnPaused();
        }
Пример #3
0
        private void Thread_Completed(object sender, ThreadExitedArgs e)
        {
            bool isRaiseCompleted = false;

            lock (this._syncRoot)
            {
                if (e.WorkID != this._workID)
                {
                    return;                          // 这次操作已经过期
                }
                if (this._status != DownloaderStatuses.Downloading)
                {
                    return;                                                // 只有Downloading状态才可能变为Failed状态
                }
                if (!this._writer.IsCompleted())
                {
                    return;                             // 文件下载还没有完成
                }
                this.RefreshWorkID();
                this._status = DownloaderStatuses.Completed;
                this._progressTimer.Dispose();
                this._progressTimer = null;
                this.ClearThread();
                this._sourceProvider = null;
                this._writer.Dispose();
                this._writer = null;

                if (File.Exists(this._savePath))
                {
                    File.Delete(this._savePath);
                }
                File.Move(this._tmpPath, this._savePath);
                if (File.Exists(this._configPath))
                {
                    File.Delete(this._configPath);
                }

                isRaiseCompleted = true;
            }// lock

            if (isRaiseCompleted)
            {
                this.OnCompleted();
            }
        }
Пример #4
0
        /// <summary>
        /// 取消,会删除已经下载的文件
        /// </summary>
        public void Cancel()
        {
            lock (this._syncRoot)
            {
                if (this._status == DownloaderStatuses.Completed)
                {
                    return;                                               // 如果已经下载完成则Cancel无效
                }
                if (this._status == DownloaderStatuses.Cancelled)
                {
                    return;                                               // 如果已经取消了,则不能重复操作
                }
                if (this._status == DownloaderStatuses.Downloading)
                {
                    // 刷新WorkID
                    this.RefreshWorkID();
                    this._progressTimer.Dispose();
                    this._progressTimer = null;
                    this.ClearThread();
                    // 清空SourceProvider
                    this._sourceProvider = null;
                    // 释放Writer
                    this._writer.Dispose();
                    this._writer = null;
                }// if

                this._status = DownloaderStatuses.Cancelled;
                // 删除临时文件
                if (File.Exists(this._tmpPath))
                {
                    File.Delete(this._tmpPath);
                }
                // 删除配置文件
                if (File.Exists(this._configPath))
                {
                    File.Delete(this._configPath);
                }
            }// lock

            this.OnCancelled();
        }
Пример #5
0
        /// <summary>
        /// 开始下载
        /// </summary>
        public async void Start()
        {
            long           workID;
            SourceProvider sourceProvider;

            lock (this._syncRoot)
            {
                if (this._status == DownloaderStatuses.Downloading)
                {
                    throw new Exception("Downloader is working.");
                }
                if (this._status == DownloaderStatuses.Completed)
                {
                    throw new Exception("Downloader is completed.");
                }

                this._status = DownloaderStatuses.Downloading; // 设置Downloader状态

                // 生成新的workID
                workID = this.RefreshWorkID();

                // 重置SourceProvider
                var protocalProvider = new HttpProtocalProvider();
                var mirrorSelector   = new SequentialMirrorSelector();
                mirrorSelector.Initialize(this._config.MainSource, this._config.Mirrors);
                sourceProvider       = new SourceProvider(mirrorSelector, protocalProvider);
                this._sourceProvider = sourceProvider;
            }// lock

            // 初始化SourceProvider
            await sourceProvider.InitializeAsync(CancellationToken.None);

            lock (this._syncRoot)
            {
                // 检测当前操作是否过期
                if (workID != this._workID)
                {
                    return;
                }

                var newRemoteFileInfo = this._sourceProvider.GetRemoteFileInfo();

                // 对文件进行分片
                List <LocalSegment> segments = new List <LocalSegment>();
                if (this._config.HasSegment &&
                    this._config.RemoteInfo != null &&
                    RemoteFileInfo.IsSameFile(this._config.RemoteInfo, newRemoteFileInfo))
                {
                    // 如果文件已经分片,服务器文件信息与缓存的文件信息一致则用缓存的文件分片
                    segments.AddRange(this._config.Segments);
                }

                // 如果没有分片或则缓存的文件已经过时了则重新分片
                if (segments.Count == 0)
                {
                    if (newRemoteFileInfo.IsAcceptRange)// 如果文件支持分段下载
                    {
                        var calculateSegments = this._segmentCalculator.GetSegments(this._maxThreadCount, newRemoteFileInfo);
                        foreach (var calculateSegment in calculateSegments)
                        {
                            segments.Add(new LocalSegment
                            {
                                StartPosition = calculateSegment.StartPosition,
                                EndPosition   = calculateSegment.EndPosition
                            });
                        }
                    }
                    else// 如果文件不支持分段下载
                    {
                        if (newRemoteFileInfo.Size <= 0)
                        {
                            throw new Exception(string.Format("Remote file size invalid, size: {0}.", newRemoteFileInfo.Size));
                        }
                        // 整个文件只有一个片段
                        segments.Add(new LocalSegment
                        {
                            StartPosition = 0,
                            EndPosition   = newRemoteFileInfo.Size - 1
                        });
                        // 设置最大线程数为1
                        this._maxThreadCount = 1;
                    } // else
                }     // if

                // 创建LocalFileWriter
                this._writer = new LocalFileWriter(this._tmpPath, segments, this._cacheLength);
                this._writer.CreateFile();

                // 缓存文件配置
                this.CacheConfig();

                // 创建下载线程
                this._threads = new List <SegmentThread>();
                for (int i = 0; i < this._maxThreadCount; i++)
                {
                    var thread = new SegmentThread(i + 1, this._writer, this._sourceProvider, workID);
                    thread.Completed += Thread_Completed;
                    thread.Failed    += Thread_Failed;
                    this._threads.Add(thread);
                }

                // 启动下载线程
                foreach (var thread in this._threads)
                {
                    thread.Start();
                }

                this._lastProgressChangeTime = DateTime.Now;
                this._lastDownloadedSize     = this._writer.GetDownloadedSize();
                this._progressTimer          = new Timer(ProgressTimer_Callback, workID, ProgressTimerInterval, Timeout.Infinite);
            }// lock

            this.OnStarted();
        }