Example #1
0
        /// <summary>
        /// 开始下载文件
        /// </summary>
        /// <returns></returns>
        public async Task DownloadFile()
        {
            _logger.LogInformation($"Start download Url={Url} File={File.FullName}");

            var(response, contentLength) = await GetContentLength();

            FileStream = File.Create();
            FileStream.SetLength(contentLength);
            FileWriter = new RandomFileWriter(FileStream);

            SegmentManager = new SegmentManager(contentLength);

            _progress.Report(new DownloadProgress($"file length = {contentLength}", SegmentManager));

            var downloadSegment = SegmentManager.GetNewDownloadSegment();

            // 下载第一段
            Download(response, downloadSegment);

            var supportSegment = await TryDownloadLast(contentLength);

            var threadCount = 1;

            if (supportSegment)
            {
                // 多创建几个线程下载
                threadCount = 10;

                for (var i = 0; i < threadCount; i++)
                {
                    Download(SegmentManager.GetNewDownloadSegment());
                }
            }

            for (var i = 0; i < threadCount; i++)
            {
                _ = Task.Run(DownloadTask);
            }

            await FileDownloadTask.Task;
        }
        /// <summary>
        /// 开始下载文件
        /// </summary>
        /// <returns></returns>
        public async Task DownloadFileAsync()
        {
            _logger.LogInformation($"Start download Url={Url} File={File.FullName}");

            var(response, contentLength) = await GetContentLength();

            _logger.LogInformation($"ContentLength={contentLength}");

            if (contentLength < 0)
            {
                // contentLength == -1
                // 当前非下载内容,没有存在长度
                // 可测试使用的链接是 https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.100-preview.7-windows-x64-installer
                _logger.LogWarning($"Can not download file. ContentLength={contentLength}");
                return;
            }

            FileStream = File.Create();
            FileStream.SetLength(contentLength);
            FileWriter = new RandomFileWriterWithOrderFirst(FileStream);
            FileWriter.StepWriteFinished += (sender, args) => SharedArrayPool.Return(args.Data);

            SegmentManager = new SegmentManager(contentLength);

            _progress.Report(new DownloadProgress($"file length = {contentLength}", SegmentManager));

            var downloadSegment = SegmentManager.GetNewDownloadSegment();

            // 下载第一段
            Download(response, downloadSegment !);

            var supportSegment = await TryDownloadLast(contentLength);

            int threadCount;

            if (supportSegment)
            {
                // 先根据文件的大小,大概是 1M 让一个线程下载,至少需要开两个线程,最多是 10 个线程
                threadCount = Math.Max(Math.Min(2, (int)(contentLength / 1024 / 1024)), MaxThreadCount);
            }
            else
            {
                // 不支持分段下载下,多个线程也没啥用
                threadCount = 1;
            }

            if (supportSegment)
            {
                // 多创建几个线程下载
                for (var i = 0; i < threadCount; i++)
                {
                    Download(SegmentManager.GetNewDownloadSegment());
                }

                //控制开关,如果下载阻塞就先暂停
                ControlSwitch();
            }

            // 一开始就创建足够量的线程尝试下载
            for (var i = 0; i < threadCount; i++)
            {
                StartDownloadTask();
            }

            await FileDownloadTask.Task;
        }