【问题标题】:download rate for a downloader using C#使用 C# 的下载器的下载速率
【发布时间】:2014-10-21 12:59:15
【问题描述】:

我想在我的下载器中实现下载速率。谷歌搜索后发现一个相当复杂的应用程序Download manager - limit download speed。然后,在另一个线程https://stackoverflow.com/questions/26073779/how-to-add-download-rate-and-limit-rate-in-downloader-in-c-sharp 上找到了一个很好的建议:

设置一个每秒触发一次的计时器,并使用计数器记录已下载的字节数,在计时器 Tick 事件中将下载速率报告为 x Bytes/s,并将计数器重置为零

刚刚开始实现这个,使用

bytesIn = int.Parse(e.BytesReceived.ToString());
totalBytes = int.Parse(e.TotalBytesToReceive.ToString());

我的代码中有 bytesIn 显示已接收字节数,但如何使用计时器实现上面引用的建议,就好像我使用 tick() 事件并在每个 tick() 事件上计数它不会显示我的失败-速度。

请给点建议?

【问题讨论】:

  • 还要跟踪目前的总下载时间...但是这个建议只是为了显示速率,而不是限制它。你想做什么?
  • 顺便说一句,发送方的 TCP 速率控制很容易,通过使用延迟或丢弃的 ACK 来创建背压,在接收方网络堆栈中几乎不可能,而仅使用高级 API 的接收方则不可能。如果不希望 TCP 确定速率,则需要应用层的速率控制命令,以获得发送方的帮助。

标签: c# winforms webclient


【解决方案1】:

您需要做的是在计时器期间记录bytesIn 并将其存储起来以备后用。下次计时器触发时(一秒后),您获取新的bytesIn 值,然后减去之前的值。这将为您提供最后一秒下载的字节数。您可以在屏幕上将此数字显示为#### Bytes/s,也可以将该数字除以1024,然后将结果显示为#### Kbytes/s

long lastDownload = 0;
long bytesIn = 0

//This is a event for a timer that fires once per second on the UI thread.
private void TimerTick(object sender, EventArgs e)
{
     //Figure out how many bytes where downloaded in the last second.
     var bytesDownloadedLastSecond = bytesIn - lastsDownload;

     //Copy the number over for the next firing of TimerTick.
     lastDownload = bytesIn;


     double scalingFactor;    
     string formatText;

     //Figure out if we should display in bytes, kilobytes or megabytes per second.
     if(bytesDownloadedLastSecond < 1024)
     {
          formatText = "{0:N0} B/sec";
          scalingFactor = 1;
     }
     else if(bytesDownloadedLastSecond < 1024 * 1024)
     {
          formatText = "{0:N2} Kb/sec";
          scalingFactor = 1024;
     }
     else
     {
          formatText = "{0:N2} Mb/sec";
          scalingFactor = 1024 * 1024;
     }

     //Display the speed to the user, scaled to the correct size.
     speedTextBox.Text = String.Format(formatText, bytesDownloadedLastSecond / scalingFactor );
}

private void DownloadProgress(object sender, EventArgs e)
{
    bytesIn = int.Parse(e.BytesReceived.ToString());
    totalBytes = int.Parse(e.TotalBytesToReceive.ToString());
}

【讨论】:

  • ... 除了使用实际时间,而不是请求的计时器间隔。更好的是实际接收数据的时间(如果数据停止到来,则回退到计时器时间)。还有一些平均。
  • @BenVoigt 非常正确,这只是餐巾纸编程的一些非常快速的回溯。对于 OP,您可以做很多事情来获得“更好”的速度指示器,不要将我的回答视为“唯一的方法”。
  • ' speedTextBox '。即使使用谷歌@ScottChamberlain 也无法弄清楚
  • @DavProgMania 是表单上控件的占位符名称,用于打印速度。它可以很容易地替换为Console.WriteLine(String.Format(formatText, bytesDownloadedLastSecond / scalingFactor ));
  • @ScottChamberlain 你能看一下吗? stackoverflow.com/questions/26504979/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-11
  • 2022-11-02
  • 1970-01-01
  • 2013-08-27
相关资源
最近更新 更多