Maison >développement back-end >C++ >Comment implémenter une barre de progression avec HttpClient dans .NET ?

Comment implémenter une barre de progression avec HttpClient dans .NET ?

Barbara Streisand
Barbara Streisandoriginal
2025-01-12 18:57:43782parcourir

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

Utilisez HttpClient pour implémenter la barre de progression dans .NET

L'interface IProgress<T> introduite dans .NET 4.5 permet la gestion des rapports de progression asynchrones, implémentant ainsi la fonctionnalité de barre de progression pour le téléchargement de fichiers à l'aide de HttpClient.

Méthodes d'extension utilisant IProgress<T>

Crée une méthode d'extension pour l'opération DownloadAsync de HttpClient qui accepte une implémentation IProgress<float> comme paramètre. Cette implémentation mettra à jour la barre de progression ou l'interface utilisateur avec l'état du téléchargement.

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

Dans cette méthode, la méthode progress.Report() transmettra la progression actuelle du téléchargement (en pourcentage) à votre implémentation IProgress<float>, lui permettant de mettre à jour la barre de progression ou d'autres éléments de l'interface utilisateur en conséquence.

Extension de flux pour les rapports d'avancement

Pour gérer les rapports de progression réels au fur et à mesure que les données sont écrites dans le flux cible, envisagez de créer une méthode d'extension pour la classe 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>

Cette méthode d'extension surveille le nombre d'octets écrits dans le flux cible et signale la progression à l'aide de l'implémentation IProgress<long> transmise.

En combinant ces méthodes d'extension, vous pouvez facilement implémenter la fonctionnalité de barre de progression pour les opérations de téléchargement de fichiers à l'aide de HttpClient.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn