1

This is the method that calculate the speed of download:

private void CalculateDownload(int ln, BackgroundWorker backw)
{
    string speed;
    DateTime DownloadStart = DateTime.Now;

    int dnsize = ln;

    if (dnsize > 0)
    {
        DateTime DownloadEnd = DateTime.Now;
        TimeSpan DownloadSub = DownloadEnd.Subtract(
            DownloadStart);

        speed = string.Format("Download speed: {0:F0} bps\n",
            (dnsize / DownloadSub.TotalMilliseconds) * 1000);
        backw.ReportProgress(0,speed);
    }
}

And this is the method i'm using to download a file from ftp server. Each time a single file.

public int FtpDownload(object sender, string file, string filesdirectories, string fn)
{
    string tmp = "";

    BackgroundWorker bw = sender as BackgroundWorker;
    string filenameonly = Path.GetFileName(file);
    string ftpdirectories = Path.Combine(ftpcontentdir, filesdirectories);
    string fileurl = "ftp://" + file;
    FtpWebRequest reqFTP;
    reqFTP = (FtpWebRequest)FtpWebRequest.Create(fileurl);
    reqFTP.Credentials = new NetworkCredential(UserName, Password);
    reqFTP.UseBinary = true;
    reqFTP.UsePassive = true;
    reqFTP.KeepAlive = true;

    reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
    try
    {
        FtpWebResponse response = (FtpWebResponse)reqFTP.
            GetResponse();

        Stream responseStream = response.GetResponseStream();
        StreamReader reader = new StreamReader(responseStream);
        tmp = reader.ReadToEnd();
        CalculateDownload(tmp.Length, bw);
        reader.Close();
        response.Close();
    }
    catch (WebException e)
    {
        Console.WriteLine(e.ToString());
    }

    return tmp.Length;
}

The first file download in the CalculateDownload method i'm getting the file size:

The variable ln is for example 66349

Then the variable speed contain: Download speed: 21367 bps In the next file:

ln = 59892

Then speed is: Download speed: 25100 bps

That is working fine when i'm using breakpoint but if i'm not using a breakpoint instead 25100 bps i will see infinity bps

In form1 i'm sending the file to download like this:

private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i < numberOfFiles.Count; i++)
    {
        int fn = numberOfFiles[i].IndexOf(txtHost.Text, 0);
        string fn1 = numberOfFiles[i].Substring(txtHost.Text.Length + 1, numberOfFiles[i].Length - (txtHost.Text.Length + 1));
        string dirs = Path.GetDirectoryName(fn1);
        string filename = Path.GetFileName(fn1);
        ftpProgress1.FtpDownload(sender, numberOfFiles[i], dirs, filename);
    }
}

And the progress changed event in form1:

private void backgroundWorker2_ProgressChanged(object sender, ProgressChangedEventArgs e)
{           
    this.toolStripStatusLabel1.Text = e.UserState.ToString();
}

Why when i'm using breakpoint it's showing every file the speeed the time was downloaded but without breakpoint it's showing infinity ?

Andrey Korneyev
  • 26,353
  • 15
  • 70
  • 71
  • 1
    if `DownloadSub.TotalMillisecond` is 0, you will get a division by 0 – thumbmunkeys Dec 08 '14 at 14:05
  • How big are the files you are downloading and where are you getting them from? Is the function to measure the download speed called once at the end of the download? Since your size comes from string.length that will make it bytes/second, not bits/second. – MikeS159 Dec 08 '14 at 14:15
  • 1
    set `DownloadStart` at somewhere near the beginning of FtpDownload method. – kennyzx Dec 08 '14 at 14:17

2 Answers2

4

Division by 0 gives out infinity when using floats or doubles.

You could add an additional check to see if 0 miliseconds is elapsed and in that case not calculate the value. At Time = 0, since nothing is downloaded yet the value is probably not useful to the user.

You could also add unit tests by passing a class that implements an interface with the right methods to simulate the call to back.ReportProgress such as:

private void CalculateDownload(int ln, IBackgroundWorker backw)

to figure out what happens at Time = 0, Time = 1 and so on.

Finally that line:

int dnsize = ln;

is not useful since you already have the variable passed to your function

Mystra007
  • 275
  • 1
  • 9
  • I added a check before the line speed = string.Format....this check: if (DownloadSub.TotalMilliseconds != 0) but it's all the time 0. And also the start time and end time are the same identical. Not sure what is going on. – Horhe El Fenenado Dec 08 '14 at 14:30
  • Yes they are the same because you are always reinitializing the DownloadStart variable. The time between that and your calculation is probably in nanoseconds not milliseconds. You need to initialize the variable outside the CalculateDownload method and keep it as a class member so that you can refer to it Inside the CalculateDownload method. – Mystra007 Dec 08 '14 at 15:03
  • Also you may want to check http://stackoverflow.com/questions/1487146/convert-difference-between-2-times-into-milliseconds to properly calculate timespans. I don't have access to visual studio atm so I can't check for you if the way you calculate is correct. – Mystra007 Dec 08 '14 at 15:06
  • You right for moving the DownloadStart outside the method. Now it's working. For calculating the timespans i will try to see if i understand how to do it right in the link. Thank you. – Horhe El Fenenado Dec 08 '14 at 15:15
0

If you get a result when using a break point, but infinity when you let it run, I suspect you are downloading it in less than 1ms, so you are dividing by 0. You could try a larger file to see if you get a better result without break points. Alternatively consider something mote accurate like DateTime.Ticks.

Note, string.length will be bytes not bits.

MikeS159
  • 1,884
  • 3
  • 29
  • 54