コード例 #1
0
        /// <summary>
        /// 检查是否下载完成
        /// </summary>
        /// <param name="speedCalculator"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task <int> CheckDownloadInfoAsync(SpeedCalculator speedCalculator, CancellationToken cancellationToken)
        {
            var retryTasks = new List <DownloadTask>();
            var retryCount = 0;
            int errorCount = 0;
            Func <DownloadSegmentInfo, bool> predicate = GetCheckDownloadSegmentInfoFunc();

            while ((errorCount = DownloadInfo.Count(predicate)) > 0)
            {
                if (retryCount >= 3)
                {
                    break;
                }
                Console.WriteLine($"错误数据个数:{errorCount},开始第{retryCount}次重试");
                foreach (var item in DownloadInfo)
                {
                    if (predicate(item))
                    {
                        item.SrcStream = null;
                        var task = DownloadSegmentFileAsync(item, (r, percentage) =>
                        {
                            speedCalculator.CurrentValue += r;
                        }, cancellationToken);
                        retryTasks.Add(task);
                    }
                }
                await retryTasks.StartAndWaitAllThrottled(MaxThreadCount);

                retryCount++;
            }
            return(errorCount);
        }
コード例 #2
0
        /// <summary>
        /// 下载文件
        /// </summary>
        /// <param name="progressAction"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task DownloadFileAsync(Action <ProgressInfo> progressAction, CancellationToken cancellationToken = default)
        {
            if (IsDownloaded)
            {
                return;
            }
            SpeedCalculator speedCalculator = new SpeedCalculator();
            ProgressInfo    progressInfo    = new ProgressInfo();
            bool            isCompleted     = false;

            speedCalculator.Updated += async(h) =>
            {
                progressInfo.AverageSpeed = speedCalculator.AverageSpeed;
                progressInfo.CurrentValue = speedCalculator.CurrentValue;
                progressInfo.Speed        = speedCalculator.Speed;
                progressInfo.Percentage   = DownloadInfo.Percentage;
                progressInfo.TargetValue  = DownloadInfo?.Size;
                progressAction.Invoke(progressInfo);
                var count = DownloadInfo.Count(m => m.Size == 0);
                //Console.WriteLine("count " + count + " size " + DownloadInfo.Size + " read size " + DownloadInfo.TotalReadBytes);
                if (isCompleted)
                {
                    speedCalculator.Stop();
                }
                else
                {
                    await SaveDownloadInfoAsync();
                }
            };

            foreach (var segment in DownloadInfo)
            {
                if (segment.TotalReadBytes != 0 && segment.TotalReadBytes >= segment.Size)
                {
                    continue;
                }
                var task = DownloadSegmentFileAsync(segment, (r, percentage) =>
                {
                    speedCalculator.CurrentValue += r;
                }, cancellationToken);
                FileSegmentaionTasks.Add(task);
            }
            speedCalculator.Start();
            await FileSegmentaionTasks.StartAndWaitAllThrottled(MaxThreadCount);

            var errorCount = await CheckDownloadInfoAsync(speedCalculator, cancellationToken);

            ///错误数量
            if (errorCount == 0)
            {
                await ReconstructSegmentsAsync();
                await CompleteAsync(true);
            }
            isCompleted = true;
        }