.net8 下载文件+进度条
效果:

代码:
1、异步下载代码
展开或折叠代码
 public async Task DownloadFileAsync(string url, string savePath, IProgress<FileDownloadInfo> progress, CancellationToken cancelToken)
 {
     using HttpClient client = new();
     //指定HttpCompletionOption.ResponseHeadersRead来立即处理响应头而不是等待内容完全下载
     using HttpResponseMessage response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, cancelToken);
     using Stream stream = await response.Content.ReadAsStreamAsync(cancelToken);
     using FileStream fileStream = new(savePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true);
     //TCP/IP协议数据包通常也是8kb,所以buffer的长度与之匹配。
     byte[] buffer = new byte[8192];
     int bytesRead;
     long totalBytesRead = 0;
     long totalBytes = response.Content.Headers.ContentLength ?? -1;
     var stopwatch = new Stopwatch();
     stopwatch.Start();
     while (!cancelToken.IsCancellationRequested && (bytesRead = await stream.ReadAsync(buffer, cancelToken)) > 0)
     {
         await fileStream.WriteAsync(buffer.AsMemory(0, bytesRead), cancelToken);
         totalBytesRead += bytesRead;
         double speed = 0;
         if (stopwatch.Elapsed.TotalSeconds > 0)
         {
             speed = totalBytesRead / stopwatch.Elapsed.TotalSeconds;
         }
         var value = (int)(((double)totalBytesRead / totalBytes) * 100);
         progress.Report(new FileDownloadInfo
         {
             Size = totalBytes,
             Downloaded = totalBytesRead,
             Progress = value,
             Speed = speed,
             Remaining = (int)((totalBytes - totalBytesRead) / speed)
         });
     }
     cancelToken.ThrowIfCancellationRequested();
 } 
2、创建一个文件下载信息类
展开或折叠代码
public class FileDownloadInfo : IDisposable
{
    /// <summary>
    /// 文件大小
    /// </summary>
    public long Size { get; set; }
    /// <summary>
    /// 已下载
    /// </summary>
    public long Downloaded { get; set; }
    /// <summary>
    /// 下载速度
    /// </summary>
    public double Speed { get; set; }
    /// <summary>
    /// 下载进度
    /// </summary>
    public int Progress { get; set; }
    /// <summary>
    /// 预计剩余时间
    /// </summary>
    public int Remaining { get; set; }
    public void Dispose()
    {
        GC.SuppressFinalize(this);
    }
}
    3.1、定义一个Progress
展开或折叠代码
var progress = new Progress<FileDownloadInfo>(info =>
{
    //todo 处理异步方法中Report过来的数据,比如下载进度、下载速度等。
});
展开或折叠代码
await DownloadFileAsync(url, path, progress, _cancellationTokenSource.Token);
4.1、定义一个取消令牌
展开或折叠代码
private CancellationTokenSource? _cancellationTokenSource = new CancellationTokenSource();
4.2、调用异步下载方法时传入令牌。
    4.3、在需要取消下载的时候调用令牌的Cancel()方法
展开或折叠代码
_cancellationTokenSource?.Cancel();
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号