【问题标题】:C#, Calculating Download Speed, Where's The Problem?C#,计算下载速度,问题出在哪里?
【发布时间】:2011-11-04 10:13:40
【问题描述】:

我想将下载速度计算为 kbps(每秒 kb)。代码有问题,它没有显示实际速度。我真的厌倦了这项工作。此外,当使用(TotalDownloadSize / ElapsedTime) 公式时,它会显示更真实的结果,但您知道它会得到平均值,这将是愚蠢的。

它通常给出 4000,基本上是因为块 4096,当我将它设置为 128 时,我得到 50/100/125 值。

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();
    }

}

那么问题出在哪里?

【问题讨论】:

  • 强制漫画:xkcd.com/612
  • 并注意:后台工作人员已经有一个 ProgressChanged 事件,没有理由自己进行回调。如果你这样做了,看看 BeginInvoke()。
  • 我见过的大多数“当前速度”测量结果似乎显示“迄今为止的平均速度”(到目前为止的总下载大小除以迄今为止的总经过时间)。
  • 我想实时进行。
  • 嗯,实时 == 不准确

标签: c# networking download


【解决方案1】:

好吧,我的第一条评论是你的代码不是线程安全的,所以当你设置 dlElapsed = DateTime.Now; 时,dlElapsed 的值与 UpdateProgress 将要检查的值不同。

【讨论】:

  • @Henk Holterman - 想解释一下“足够安全”的评论吗?有一个从两个单独的线程访问的类变量,没有太多的同步尝试。
  • 它 (dlElapsed) 仅从 UpdateProgress 访问,并提供更好但仍然愚蠢的结果。它通常给 1600。
  • 该值在首次使用之前设置(一次)。之后,只有进度代码使用它。但你是对的,正确的做法是在调用 RunWorkserAsync() 之前设置它
  • @PythEch - 如果它给出“愚蠢”的结果,那么它可能是你的方法。
  • @ramhound:不,看看代码。任何线程问题只会影响显示的第一个值。之后 dlElpsed 仅由 1 个线程使用。
【解决方案2】:

那么问题出在哪里?

您正在粗略地采样变化很大的东西。

考虑缓冲测量结果并平均最后 5 个左右。寻找“运行平均值”的实现。

【讨论】:

  • 但这不是程序化的方式。
  • 而且,它不起作用(在 15 年 5 月 10 日重置 dlElapsed 的结果)给出了超不合逻辑的速度结果。 ://
  • 我没有提到或意味着重置 dlElapsed。
  • @PythEch - “编程方式”是什么意思。进行最后 5 次计算并得出平均值将是显示您想要的结果的有效方式。
  • @PythEch - 正如 Daniel B 指出的那样。您应该解决当前代码的一些基本问题。
猜你喜欢
  • 2022-10-23
  • 1970-01-01
  • 1970-01-01
  • 2011-05-16
  • 2010-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
相关资源
最近更新 更多