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");
}
}