Hi @jdoe doe , Welcome to Microsoft Q&A,
First you can follow Viorel's advice and modify the part of your download speed calculation.
Secondly, you can add a Queue<double> speedHistory
to store the history of download speed in order to calculate the moving average. This makes the speed relatively accurate.
private DateTime startTime;
void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
double newBytesIn = e.BytesReceived;
double newTotalBytes = e.TotalBytesToReceive;
double percentage = newBytesIn / newTotalBytes * 100;
// Update progress bar
progressBar1.Value = (int)Math.Truncate(percentage);
// Calculate download speed
DateTime now = DateTime.Now;
TimeSpan timeElapsed = now - lastProgressUpdateTime;
if (timeElapsed.TotalMilliseconds > 500) // Update speed every 500 milliseconds
{
long bytesSinceLastUpdate = e.BytesReceived - lastProgressUpdateBytes;
double speedInBytesPerSecond = bytesSinceLastUpdate / timeElapsed.TotalSeconds;
// Fix the negative problem
if (speedInBytesPerSecond < 0)
{
speedInBytesPerSecond = 0;
}
// Add the speed to the history
speedHistory.Enqueue(speedInBytesPerSecond);
if (speedHistory.Count > 5) // You can adjust the number of elements to use in the moving average
{
speedHistory.Dequeue();
}
// Calculate average speed
double averageSpeed = speedHistory.Average();
// Display download speed
lblSpeedReporter.Text = FormatBytes(averageSpeed) + "/s";
lastProgressUpdateTime = now;
lastProgressUpdateBytes = e.BytesReceived;
}
// Display downloaded size
lblSizeReporter.Text = string.Format("{0} / {1}", FormatBytes(newBytesIn), FormatBytes(newTotalBytes));
// Calculate time left
if (newBytesIn > 0 && newBytesIn < newTotalBytes)
{
double downloadRate = averageSpeed; // Use the average speed
double remainingBytes = newTotalBytes - newBytesIn;
double timeLeftInSeconds = remainingBytes / downloadRate;
if (timeLeftInSeconds > 0)
{
TimeSpan timeLeft = TimeSpan.FromSeconds(timeLeftInSeconds);
// Display time left
lblTimeLeftReporter.Text = string.Format("{0:D2}:{1:D2}:{2:D2}", timeLeft.Hours, timeLeft.Minutes, timeLeft.Seconds);
}
}
}
string FormatBytes(double bytes)
{
string[] suffixes = { "B", "KB", "MB", "GB", "TB" };
int suffixIndex = 0;
while (bytes >= 1024 && suffixIndex < suffixes.Length - 1)
{
bytes /= 1024;
suffixIndex++;
}
return string.Format("{0:0.##} {1}", bytes, suffixes[suffixIndex]);
}
Best Regards,
Jiale
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.