0

I have a little problem I can only get the download speed if the download per file is done. How can I get the Realtime download speed? I mean while reading the totalBytesRead from the response. The download speed will show also not only at the end of the download.

Here's my current code that got from somewhere here and a little modified.

This is the code from my GUI:


private async Task ProgressUpdate(string url, CancellationToken ct)
{
    var client = new Downloader(url, OutputFragmentFilePath);
    if (client != null)
    {
        var startTime = DateTime.Now;
        client.ProgressChanged += (totalFileSize, totalBytesDownloaded, 
            progressPercentage) =>
            {
                sw.Start();
                var endTime = DateTime.Now;

                double tSpan = (endTime - startTime).TotalSeconds;
                var downloadSpeed = Utils.FormatDownloadSpeed(totalFileSize.Value, tSpan);
                Text = downloadSpeed;
               
                //In here I have the progressbar and I want also to 
                //include the downloadspeed while downloading.

                PB.Value = Convert.ToInt32(progressPercentage);
            };

        await client.StartDownload(ct);

        lvi.SubItems[2].Text = "Completed";
    }
}

In my Download Class:

private enum BufferSize
{
    bs1 = 4096,     //4 * 1024 = 4096
    bs2 = 8192,     //8 * 1024 = 8192
    bs3 = 40960,    //40 * 1024 = 40960
};

private async Task DownloadFileFromHttpResponseMessage(
    HttpResponseMessage response, CancellationToken token)
{
    HttpStatusCode statusCode = response.StatusCode;
    if (!response.IsSuccessStatusCode) { 
        throw new Exception($"{statusCode}  {(int)statusCode}"); 
    }

    using (var responseStream = await response.Content.ReadAsStreamAsync())
    {
        long totalBytes = response.Content.Headers.ContentLength ?? 0;
        long totalBytesRead = 0;
        long readCount = 0;

        byte[] buffer = new byte[(int)BufferSize.bs2];
        bool isMoreToRead = true;

        using (var fileStream = new FileStream(OutputFilePath, 
            FileMode.Create, 
            FileAccess.Write, 
            FileShare.None))
        {
            do
            {
                token.ThrowIfCancellationRequested();
                int bytesRead = await responseStream.ReadAsync(buffer, 
                    0, buffer.Length, token);
                if (bytesRead == 0)
                {
                    isMoreToRead = false;
                    TriggerProgressChanged(totalBytes, totalBytesRead);
                    continue;
                }
                await fileStream.WriteAsync(buffer, 0, bytesRead);

                totalBytesRead += bytesRead;
                readCount += 1;

                if (readCount % 10 == 0)
                {
                    TriggerProgressChanged(totalBytes, totalBytesRead);
                }
            }
            while (isMoreToRead);
        }
        TriggerProgressChanged(totalBytes, totalBytesRead);
    }
}
private void TriggerProgressChanged(long? totalDownloadSize, 
    long totalBytesRead)
{
    if (ProgressChanged == null) { return; }

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

Format download speed: (thanks to Fildor)

public static string FormatDownloadSpeed(double size, double tspan)
{
    string message = "Download Speed: ";
    if (size / tspan > 1024 * 1024) {
        return string.Format(message + "{0:N1} {1}", size / (1024 * 1204) / tspan, "MB/s");
    }
    else if (size / tspan > 1024){
        return string.Format(message + "{0:N0} {1}", size / 1024 / tspan, "KB/s");
    }
    else{
        return string.Format(message + "{0:N1} {1}", size / 1024 / tspan, "KB/s");
    }
}
Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
Maherz123
  • 67
  • 5
  • Have a look at this: https://stackoverflow.com/a/46497896/982149. Key to a solution is the setting of `HttpCompletionOption.ResponseHeadersRead` which completes the task as soon as the headers have been read but the download is not already complete. – Fildor Oct 07 '20 at 11:49
  • Alright I'll take a look – Maherz123 Oct 07 '20 at 11:54
  • I tried it now but I can't understand how I can pass the progress report to my GUI. I used the method from your link – Maherz123 Oct 07 '20 at 12:40
  • @IanKemp I'll take a look – Maherz123 Oct 07 '20 at 12:42
  • @IanKemp The method below from your link is what I'm using. But my question actually is where to put the download speed so that I can get the actually speed while downloading – Maherz123 Oct 07 '20 at 12:46

0 Answers0