Antara muka IProgress<T>
yang diperkenalkan dalam .NET 4.5 membenarkan pengendalian pelaporan kemajuan tak segerak, sekali gus melaksanakan fungsi bar kemajuan untuk memuat turun fail menggunakan HttpClient.
IProgress<T>
Mencipta kaedah sambungan untuk operasi DownloadAsync
HttpClient yang menerima pelaksanaan IProgress<float>
sebagai parameter. Pelaksanaan ini akan mengemas kini bar kemajuan atau UI dengan status muat turun.
<code class="language-csharp">public static async Task DownloadAsync(this HttpClient client, string requestUri, Stream destination, IProgress<float> progress = null, CancellationToken cancellationToken = default) { // 首先获取 http 头信息以检查内容长度 using (var response = await client.GetAsync(requestUri, HttpCompletionOption.ResponseHeadersRead)) { var contentLength = response.Content.Headers.ContentLength; using (var download = await response.Content.ReadAsStreamAsync(cancellationToken)) { // 未传递进度报告器或内容长度未知时忽略进度报告 if (progress == null || !contentLength.HasValue) { await download.CopyToAsync(destination); return; } // 将绝对进度(已下载字节数)转换为相对进度(0% - 100%) var relativeProgress = new Progress<long>(totalBytes => progress.Report((float)totalBytes / contentLength.Value)); // 使用扩展方法在下载时报告进度 await download.CopyToAsync(destination, 81920, relativeProgress, cancellationToken); progress.Report(1); // 报告100%完成 } } }</code>
Dalam kaedah ini, kaedah progress.Report()
akan menghantar kemajuan muat turun semasa (dalam peratus) kepada pelaksanaan IProgress<float>
anda, membolehkannya mengemas kini bar kemajuan atau elemen UI lain dengan sewajarnya.
Untuk mengendalikan pelaporan kemajuan sebenar semasa data ditulis kepada strim sasaran, pertimbangkan untuk membuat kaedah sambungan untuk kelas Strim.
<code class="language-csharp">public static async Task CopyToAsync(this Stream source, Stream destination, int bufferSize, IProgress<long> progress = null, CancellationToken cancellationToken = default) { if (source == null) throw new ArgumentNullException(nameof(source)); if (!source.CanRead) throw new ArgumentException("必须可读", nameof(source)); if (destination == null) throw new ArgumentNullException(nameof(destination)); if (!destination.CanWrite) throw new ArgumentException("必须可写", nameof(destination)); if (bufferSize < 0) throw new ArgumentOutOfRangeException(nameof(bufferSize)); var buffer = new byte[bufferSize]; long totalBytesRead = 0; int bytesRead; while ((bytesRead = await source.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false)) != 0) { await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false); totalBytesRead += bytesRead; progress?.Report(totalBytesRead); } }</code>
Kaedah sambungan ini memantau bilangan bait yang ditulis kepada strim sasaran dan melaporkan kemajuan menggunakan pelaksanaan IProgress<long>
yang diluluskan.
Dengan menggabungkan kaedah sambungan ini, anda boleh melaksanakan fungsi bar kemajuan dengan mudah untuk operasi muat turun fail menggunakan HttpClient.
Atas ialah kandungan terperinci Bagaimana untuk Melaksanakan Bar Kemajuan dengan HttpClient dalam .NET?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!