How can I make the Download Amount to be shown in other units so the user can read it easier ? now it's just a long number. The Dowlnoad Amount show how much size downloaded from the entire size of the file so far.

Shalva Gabriel 61 Reputation points
2021-10-20T14:49:26.87+00:00
    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;  
            }  
        }  
    }  

142171-11.jpg

In the screenshot two problem :

  1. The Download Amount should show the current downloaded size out of the completed file size but it show it as a very long number and I need it to be show in some other size unit. Something the user can read it easier.
Developer technologies | Windows Forms
Developer technologies | C#
0 comments No comments
{count} votes

Accepted answer
  1. Karen Payne MVP 35,586 Reputation points Volunteer Moderator
    2021-10-20T15:59:03.567+00:00

    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.

    142174-figure1.png

    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]);  
      
            }  
        }  
    }  
      
    
    1 person found this answer helpful.
    0 comments No comments

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.