When using httpclient to download multiple files why it's showing the progress download of one file only and then downloading the rest of the files?

Viewed 49

form1 code :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net.Http;
using System.IO;
using HttpClientProgress;
using System.Text.RegularExpressions;
using System.Net.Http.Headers;

namespace HttpClient_Test
{
    public partial class Form1 : Form
    {
        private Radar radar;

        public Form1()
        {
            InitializeComponent();

            radar = new Radar(@"d:\Test\");
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        async Task DownloadFiles()
        {
            for (int i = 0; i < radar.links.Count; i++)
            {
                using (var client = new HttpClientDownloadWithProgress(radar.links[i], @"d:\Test\r" + i.ToString() + ".gif"))
                {
                    client.ProgressChanged += (totalFileSize, totalBytesDownloaded, progressPercentage) =>
                    {
                        label1.Text = $"{progressPercentage}% ({totalBytesDownloaded}/{totalFileSize})";
                        progressBar1.Value = (int)progressPercentage;
                    };
                    await client.StartDownload();
                }
            }
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            await radar.GETR();
        }

        private async void button2_Click(object sender, EventArgs e)
        {
            await DownloadFiles();
        }
    }
}

i'm using for loop and the progressBar1.Value is changing from 0% to 100% and i see the size of the file downloaded but that's for one file only after that it's downloading the whole files.

and i want it to download file by file but also to show progress for each file download and not for only one file.

The class HttpClientDownloadWithProgress :

using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;

public class HttpClientDownloadWithProgress : IDisposable
{
    private readonly string _downloadUrl;
    private readonly string _destinationFilePath;

    private HttpClient _httpClient;

    public delegate void ProgressChangedHandler(long? totalFileSize, long totalBytesDownloaded, double? progressPercentage);

    public event ProgressChangedHandler ProgressChanged;

    public HttpClientDownloadWithProgress(string downloadUrl, string destinationFilePath)
    {
        _downloadUrl = downloadUrl;
        _destinationFilePath = destinationFilePath;
    }

    public async Task StartDownload()
    {
        _httpClient = new HttpClient { Timeout = TimeSpan.FromDays(1) };

        _httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0 Chrome");

        using (var response = await _httpClient.GetAsync(_downloadUrl, HttpCompletionOption.ResponseHeadersRead))

           await DownloadFileFromHttpResponseMessage(response);
    }

    private async Task DownloadFileFromHttpResponseMessage(HttpResponseMessage response)
    {
        try
        {
            response.EnsureSuccessStatusCode();

            var totalBytes = response.Content.Headers.ContentLength;

            using (var contentStream = await response.Content.ReadAsStreamAsync())
                await ProcessContentStream(totalBytes, contentStream);
        }
        catch
        {

        }
    }

    private async Task ProcessContentStream(long? totalDownloadSize, Stream contentStream)
    {
        var totalBytesRead = 0L;
        var readCount = 0L;
        var buffer = new byte[8192];
        var isMoreToRead = true;

        using (var fileStream = new FileStream(_destinationFilePath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, true))
        {
            do
            {
                var bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length);
                if (bytesRead == 0)
                {
                    isMoreToRead = false;
                    TriggerProgressChanged(totalDownloadSize, totalBytesRead);
                    continue;
                }

                await fileStream.WriteAsync(buffer, 0, bytesRead);

                totalBytesRead += bytesRead;
                readCount += 1;

                if (readCount % 100 == 0)
                    TriggerProgressChanged(totalDownloadSize, totalBytesRead);
            }
            while (isMoreToRead);
        }
    }

    private void TriggerProgressChanged(long? totalDownloadSize, long totalBytesRead)
    {
        if (ProgressChanged == null)
            return;

        double? progressPercentage = null;
        if (totalDownloadSize.HasValue)
            progressPercentage = Math.Round((double)totalBytesRead / totalDownloadSize.Value * 100, 2);

        ProgressChanged(totalDownloadSize, totalBytesRead, progressPercentage);
    }

    public void Dispose()
    {
        _httpClient?.Dispose();
    }
}
0 Answers
Related