Developer technologies | Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using unfreez_wrapper;
namespace Download
{
public partial class Form1 : Form
{
List<string> urls = new List<string>();
DownloadProgressTracker tracker;
public Form1()
{
InitializeComponent();
tracker = new DownloadProgressTracker(50, TimeSpan.FromMilliseconds(500));
lblDownloadProgress.Text = "";
lblStatus.Text = "Download Pending";
lblAmount.Text = "";
lblSpeed.Text = "";
urls.Add("https://speed.hetzner.de/100MB.bin");
urls.Add("https://speed.hetzner.de/100MB.bin");
}
private async Task DownloadAsync()
{
using (var client = new WebClient())
{
client.DownloadFileCompleted += (s, e) => lblStatus.Text = "Download File Completed.";
client.DownloadProgressChanged += (s, e) => tracker.SetProgress(e.BytesReceived, e.TotalBytesToReceive);
client.DownloadProgressChanged += (s, e) => lblAmount.Text = e.BytesReceived + "/" + e.TotalBytesToReceive;
client.DownloadProgressChanged += (s, e) => lblSpeed.Text = tracker.GetBytesPerSecondString();
client.DownloadProgressChanged += (s, e) => lblDownloadSize.Text = Convert.ToInt64(client.ResponseHeaders["Content-Length"]).ToString();
client.DownloadProgressChanged += (s, e) => progressBar1.Value = e.ProgressPercentage;
client.DownloadProgressChanged += (s, e) =>
{
lblDownloadProgress.Text = "%" + e.ProgressPercentage.ToString();
lblDownloadProgress.Left = Math.Min(
(int)(progressBar1.Left + e.ProgressPercentage / 100f * progressBar1.Width),
progressBar1.Width - lblDownloadProgress.Width
);
};
for (int i = 0; i < urls.Count; i++)
{
await client.DownloadFileTaskAsync(new Uri(urls[i]), @"d:\satImages\img" + i + ".gif");
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
private async void btnStart_Click(object sender, EventArgs e)
{
lblStatus.Text = "Downloading...";
await DownloadAsync();
}
private void btnStop_Click(object sender, EventArgs e)
{
lblStatus.Text = "Download Stopped";
}
}
}
And the class DownloadProgressTracker :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Download
{
class DownloadProgressTracker
{
private long _totalFileSize;
private readonly int _sampleSize;
private readonly TimeSpan _valueDelay;
private DateTime _lastUpdateCalculated;
private long _previousProgress;
private double _cachedSpeed;
private Queue<Tuple<DateTime, long>> _changes = new Queue<Tuple<DateTime, long>>();
public DownloadProgressTracker(int sampleSize, TimeSpan valueDelay)
{
_lastUpdateCalculated = DateTime.Now;
_sampleSize = sampleSize;
_valueDelay = valueDelay;
}
public void NewFile()
{
_previousProgress = 0;
}
public void SetProgress(long bytesReceived, long totalBytesToReceive)
{
_totalFileSize = totalBytesToReceive;
long diff = bytesReceived - _previousProgress;
if (diff <= 0)
return;
_previousProgress = bytesReceived;
_changes.Enqueue(new Tuple<DateTime, long>(DateTime.Now, diff));
while (_changes.Count > _sampleSize)
_changes.Dequeue();
}
public double GetProgress()
{
return _previousProgress / (double)_totalFileSize;
}
public string GetProgressString()
{
return String.Format("{0:P0}", GetProgress());
}
public string GetBytesPerSecondString()
{
double speed = GetBytesPerSecond();
var prefix = new[] { "", "K", "M", "G" };
int index = 0;
while (speed > 1024 && index < prefix.Length - 1)
{
speed /= 1024;
index++;
}
int intLen = ((int)speed).ToString().Length;
int decimals = 3 - intLen;
if (decimals < 0)
decimals = 0;
string format = String.Format("{<!-- -->{0:F{0}}}", decimals) + "{1}B/s";
return String.Format(format, speed, prefix[index]);
}
public double GetBytesPerSecond()
{
if (DateTime.Now >= _lastUpdateCalculated + _valueDelay)
{
_lastUpdateCalculated = DateTime.Now;
_cachedSpeed = GetRateInternal();
}
return _cachedSpeed;
}
private double GetRateInternal()
{
if (_changes.Count == 0)
return 0;
TimeSpan timespan = _changes.Last().Item1 - _changes.First().Item1;
long bytes = _changes.Sum(t => t.Item2);
double rate = bytes / timespan.TotalSeconds;
if (double.IsInfinity(rate) || double.IsNaN(rate))
return 0;
return rate;
}
}
}
In the screenshot two problem :
Here is a mock up which has hard coded values which of course you would need to make variable. Disregard the progress bar, not required.
using System;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private long _total = 104857600;
private readonly string _totalFormatted;
private long _current = 0;
public Form1()
{
InitializeComponent();
progressBar1.Maximum = (int)_total;
_totalFormatted = FileHelpers.SizeSuffix(_total);
}
private void button1_Click(object sender, EventArgs e)
{
_current += 5000000;
Text = $"{FileHelpers.SizeSuffix(_current)} of {_totalFormatted}";
progressBar1.Value = (int)_current > progressBar1.Maximum ? progressBar1.Maximum : (int)_current;
}
}
// place in it's own file
public class FileHelpers
{
private static readonly string[] SizeSuffixes =
{
"bytes",
"KB",
"MB",
"GB",
"TB",
"PB",
"EB",
"ZB",
"YB"
};
public static string SizeSuffix(long value, int decimalPlaces = 1)
{
if (value < 0)
{
return "-" + SizeSuffix(-value);
}
int size = 0;
var dValue = (decimal)value;
while (Math.Round(dValue, decimalPlaces) >= 1000)
{
dValue /= 1024M;
size += 1;
}
return string.Format("{0:n" + decimalPlaces + "} {1}", dValue, SizeSuffixes[size]);
}
}
}