/// <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; }