首頁 >後端開發 >C++ >如何在.NET中使用HttpClient實作進度條?

如何在.NET中使用HttpClient實作進度條?

Barbara Streisand
Barbara Streisand原創
2025-01-12 18:57:43778瀏覽

How to Implement a Progress Bar with HttpClient in .NET?

使用 HttpClient 在 .NET 中實作進度條

在 .NET 4.5 中引入的 IProgress<T> 介面允許處理非同步進度報告,從而為使用 HttpClient 下載檔案實現進度條功能。

使用 IProgress<T> 的擴充方法

為 HttpClient 的 DownloadAsync 操作建立一個擴充方法,該方法接受 IProgress<float> 實作作為參數。此實作將使用下載狀態更新進度條或 UI。

<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>

在此方法中,progress.Report() 方法會將當前下載進度(百分比)傳遞給您的 IProgress<float> 實現,從而允許它相應地更新進度條或其他 UI 元素。

流擴展用於進度報告

為了在將資料寫入目標流時處理實際的進度報告,請考慮為 Stream 類別建立一個擴充方法。

<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>

此擴充方法監視寫入目標流的位元組數,並使用傳入的 IProgress<long> 實現報告進度。

透過組合這些擴充功能,您可以輕鬆地為使用 HttpClient 的檔案下載作業實作進度條功能。

以上是如何在.NET中使用HttpClient實作進度條?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn