开发者

Calculating the progress percentage

I am using webclient to dowlnoad a file. I am calculating the progress percentage as below

  1. I know the filesize (I read it from the database table) of the file going to be downloaded.

  2. I am depending on the BytesRecieved property of WebClient to know the total bytes fetched during download.

  3. The algorithm I am using is double dProgress = (e.BytesReceived / FileSize)*100); to calculate the progress percentage.

However i am not getting correct progress percentage to update the progress bar.

Is there any method to calculate progress开发者_C百科 percentage?


Look at the following line: double dProgress = (e.BytesReceived / FileSize)*100)

If both e.BytesReceived and FileSize are integers then you will always have 0 * 100 = 0.

Make something like this:

double dProgress = ((double)e.BytesReceived / FileSize)*100.0

It is because / does integer division when dividing two integers. But you don't want that. So you convert one of the variables to double.


BytesReceived and FileSize most probably are integers so you need to calculate progress this way:

double dProgress = 100.0 * e.BytesReceived / FileSize;


If you are handling the DownloadProgressChanged event when doing an asynchronous download, the event args already has a ProgressPercentage on it, so there is no point in re-inventing it. A contrived example:

var client = new WebClient();
var reset = new ManualResetEvent(false);
client.DownloadProgressChanged += (s, e) => Console.WriteLine("{0} percent complete", e.ProgressPercentage);
client.DownloadFileCompleted += (s, e) => reset.Set();
client.DownloadFileAsync(new Uri("http://myfilepathhere.com"), "file.name");
//Block till download completes
reset.WaitOne();


The problem is that both numbers are integers. When you devide them, they become smaller than 1, so they round down to 0. Typecast them to make the result a float:

double dProgress = ((double)e.BytesReceived / FileSize)*100)


This is a very tricky problem with basic arithmetic and casting in C#.

Solution

First store the result of integer division in a double variable. And then type cast that to an integer.

int x = 5, y = 10, answer;
double ansDouble;
answer = (int)(x / y) * 100; //percentage calculation
Console.WriteLine("percentage={0}", answer);
//>output percentage=0

answer = (int)((double)x / y) * 100; //percentage calculation
Console.WriteLine("percentage={0}", answer);
//>output percentage=0

answer = (int)((double)x / (double)y) * 100; //percentage calculation
Console.WriteLine("x={0}", answer);
//>output percentage=0

answer = (int)(x/(double)y) * 100; //percentage calculation
Console.WriteLine("x={0}", answer);
//>output percentage=0

ansDouble = ((double)x / y) * 100;
answer = (int)ansDouble;
Console.WriteLine("percentage={0}", answer);
//>output percentage=50

Points to note

Turns out that x/y = 0, for any values of x and y as long as they are integers We can't solve this in one line by any casting combinations


Try this:

WebClient Client = new WebClient();
Client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(ProgressChanged);

...

  void ProgressChanged(object sender, DownloadProgressChangedEventArgs e) {

            double bytesIn = double.Parse(e.BytesReceived.ToString());
            double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
            double percentage = bytesIn / totalBytes * 100;
            int percente = int.Parse(Math.Truncate(percentage).ToString());
            progressBar.Value = percente;
        }

Or just using the ProgressPercentage value.

 void ProgressChanged(object sender, DownloadProgressChangedEventArgs e) {
           progressBar.Value = e.ProgressPercentage; 
  }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜