PythEch
PythEch

Reputation: 952

C#, Calculating Download Speed, Where's The Problem?

I want to calculate download speed as kbps (kb per second). There's a problem in the code, it doesn't show actual speed. And I'm really tired of this work. Also, when using (TotalDownloadSize / ElapsedTime) formula it shows more realistic results but you know it will get average value and it will be stupidity.

It usually gives 4000 and it's basicly because of chunk 4096 when I set it to 128 that time I get 50/100/125 values.

DateTime dlElapsed;
private delegate void UpdateProgessCallback(Int64 BytesRead, Int64 TotalBytes, Int32 CurrentBytes);
private void UpdateProgress(Int64 BytesRead, Int64 TotalBytes, Int32 CurrentBytes)
{
    DateTime Elapsed = DateTime.Now;
    var progress = Convert.ToInt32((BytesRead * 100) / TotalBytes);
    var elaps = (Elapsed - dlElapsed).TotalSeconds;
    long kbps;

    if (elaps > 0)
    {
        kbps = Convert.ToInt64((CurrentBytes / elaps) / 1024);
        updateLabelText(String.Format("Downloading ({0} kbps)...", kbps));
    }
    // Make progress on the progress bar
    if (progress < progressBar1.Maximum)
    {
        progressBar1.Value = progress;

    }
    else
    {
        progressBar1.Value = progressBar1.Maximum;
    }
    dlElapsed = DateTime.Now;
}

private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
    // Some stuff here...
    int byteSize = 0;
    byte[] downBuffer = new byte[4096];

    FileStream strLocal= new FileStream(path, FileMode.Create, FileAccess.Write);
    dlElapsed = DateTime.Now;
    while ((byteSize = stream.Read(downBuffer, 0, downBuffer.Length)) > 0)
    {
        strLocal.Write(downBuffer, 0, byteSize);
        this.Invoke(new UpdateProgessCallback(this.UpdateProgress), 
            new object[] { strLocal.Length, totalbyte, byteSize});
    }
    updateLabelText("Download complete!");
    strLocal.Close();
    }

}

So where's the problem?

Upvotes: 1

Views: 1976

Answers (2)

Henk Holterman
Henk Holterman

Reputation: 273274

So where's the problem?

You're coarsely sampling something that varies a lot.

Consider buffering measurements and averaging the last 5 or so. Look for implementations of a "running average".

Upvotes: 2

Daniel B
Daniel B

Reputation: 2887

Well, my first comment would be that your code is not thread safe, so when you set dlElapsed = DateTime.Now;, it's not the same dlElapsed value that UpdateProgress is going to be checking.

Upvotes: 1

Related Questions