-2

So I'm working on a download manager and I've implemented the pause/resume functionality as well. But in order to get the progress bar value when the download is resumed I need to get the existing length of the file before the download was stopped as well. Something like this.

    private void updateProgressBar(DownloadProgressChangedEventArgs e)
    {
        if (InvokeRequired)
            Invoke((MethodInvoker)delegate ()
            {
                updateProgressBar(e);
            });
        else
        {
            downloadProgressBar.Value = Convert.ToInt32((e.BytesReceived + existFileSize)/(e.TotalBytesToReceive + existFileSize)*100);
        }
    }

Where existFileSize is the size of the existing file after it was paused. But for some reason the progress bar only updates once the download is completed. But if i were to put lets say,

    downloadProgressBar.Value = e.ProgressPercentage;

This instead of the previous line it works perfectly but does not give the result that i want.

Any help or advice would be appreciated.

Shaanxd
  • 1
  • 1
  • Had you bothered to step through the code and examine the updates, you'd have seen that the `Value` property was always getting assigned `0` until the end. That's due to the integer division you're using. See marked duplicate for advice on how to get the division you want. – Peter Duniho Jan 30 '18 at 20:33
  • My fault I should've known. Thanks alot for the heads up :') – Shaanxd Jan 30 '18 at 21:17
  • I disagree that it's a duplicate. While the underlying cause is the same, the solution is different because this question wants an integer result from an integer division. Therefore the floating point arithmetic is unnecessary and inefficient. Just changing the order of operations as per the edit in my answer resolves the issue. – Trevor Jan 31 '18 at 08:10

2 Answers2

0

It looks like you are performing integer arithmetic. When you calculate

(e.BytesReceived + existFileSize)/(e.TotalBytesToReceive + existFileSize)

The result of this calculation is an integer, either 0 or 1. Because of this, your progress bar jumps from 0 to 100, and can't be anything in between.

Try changing the section above to:

(e.BytesReceived + existFileSize)/(double)(e.TotalBytesToReceive + existFileSize)

That will make the result of this calculation a floating point value, which will then give a value which varies between 0 and 100 as you expect.

Edit

Actually, a more efficient way would be:

downloadProgressBar.Value = Convert.ToInt32( (e.BytesReceived + existFileSize) * 100 / (e.TotalBytesToReceive + existFileSize));

Note that it now multiplies by 100 before it divides by the total to receive.

Hope this helps

Trevor
  • 1,251
  • 1
  • 9
  • 11
0

I think your division (e.BytesReceived + existFileSize)/(e.TotalBytesToReceive + existFileSize) is probably dividing an integer by an integer, which will give an integer result. And since (e.BytesReceived + existFileSize) will be less than (e.TotalBytesToReceive + existFileSize), the result you're getting will always be 0.

Instead cast these values to floats so that the result is also a float.

downloadProgressBar.Value = Convert.ToInt32((float)(e.BytesReceived + existFileSize)/(float)(e.TotalBytesToReceive + existFileSize)*100);
gunnerone
  • 3,566
  • 2
  • 14
  • 18