Example #1
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;
        }