Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何计算和显示每个文件的下载速度?_C#_.net_Winforms - Fatal编程技术网

C# 如何计算和显示每个文件的下载速度?

C# 如何计算和显示每个文件的下载速度?,c#,.net,winforms,C#,.net,Winforms,现在我添加了这个方法 private void DownloadFile() { if (_downloadUrls.Any()) { WebClient client = new WebClient(); client.DownloadProgressChanged += client_DownloadProgressChanged; client.DownloadFileCompleted += client_DownloadFileCompleted;

现在我添加了这个方法

private void DownloadFile() {

  if (_downloadUrls.Any()) {
    WebClient client = new WebClient();
    client.DownloadProgressChanged += client_DownloadProgressChanged;
    client.DownloadFileCompleted += client_DownloadFileCompleted;

    var url = _downloadUrls.Dequeue();
    string startTag = "animated/";
    string endTag = "/infra";

    int index = url.IndexOf(startTag);
    int index1 = url.IndexOf(endTag);

    string fname = url.Substring(index + 9, index1 - index - 9);
    client.DownloadFileAsync(new Uri(url), @"C:\Temp\tempframes\" + fname + ".gif");

    lastDownloadedFile = @"C:\Temp\tempframes\" + fname + ".gif";
    label1.Text = url;
    return;
  }

  // End of the download
  btnStart.Text = "Download Complete";
}

private void client_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) {
  if (e.Error != null) {
    // handle error scenario
    throw e.Error;
  }
  if (e.Cancelled) {
    // handle cancelled scenario
  }

  Image img = new Bitmap(lastDownloadedFile);
  Image[] frames = GetFramesFromAnimatedGIF(img);
  foreach(Image image in frames) {
    countFrames++;
    image.Save(@"C:\Temp\tempframes\" + countFrames + ".gif");
  }

  DownloadFile();
}

void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) {
  double bytesIn = double.Parse(e.BytesReceived.ToString());
  double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
  double percentage = bytesIn / totalBytes * 100;
  pBarFileProgress.Value = int.Parse(Math.Truncate(percentage).ToString());
  label1.Text = e.BytesReceived.ToString() + "/" + e.TotalBytesToReceive.ToString();
}
我想用这个方法或其他方法在label2上的progresschanged事件中显示下载速度。但我不知道如何使用这种方法


不确定如何在progresschanged事件中使用它。

对准备好的方法的调用
progresschanged
最适合
客户端下载progresschanged
,如下所示:

DateTime lastUpdate;
long lastBytes = 0;

private void progressChanged(long bytes) {
  if (lastBytes == 0) {
    lastUpdate = DateTime.Now;
    lastBytes = bytes;
    return;
  }

  var now = DateTime.Now;
  var timeSpan = now - lastUpdate;
  var bytesChange = bytes - lastBytes;
  var bytesPerSecond = bytesChange / timeSpan.Seconds;

  lastBytes = bytes;
  lastUpdate = now;
}
但是,您必须使用
TotalSeconds
而不是
Seconds
,否则这些值将不正确,还会导致零除异常

progressChanged(e.BytesReceived);
此帮助器类将为您跟踪收到的块、时间戳和进度:

var bytesPerSecond = bytesChange / timeSpan.TotalSeconds;
请记住,您必须在每个新文件之前或之后重置跟踪器:

//Somewhere in your constructor / initializer:
tracker = new DownloadProgressTracker(50, TimeSpan.FromMilliseconds(500));

void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    tracker.SetProgress(e.BytesReceived, e.TotalBytesToReceive);
    pBarFileProgress.Value = tracker.GetProgress() * 100;
    label1.Text = e.BytesReceived + "/" + e.TotalBytesToReceive;
    label2.Text = tracker.GetBytesPerSecondString();
}


如果您需要一些更大的文件来测试这个,我发现一些

通常是
字节/秒=上一个数据包中的字节/自上一个数据包以来的秒数
,所以看起来是正确的。稍微平滑一点(例如,保持最后10个值并显示平均值),您就有了您的下载速度。@ManfredRadlwimmer,如果您能告诉我怎么做?谢谢。当然,我会整理一个简短的例子,马上回来。我已经编辑了我的答案,应该包含你现在开始所需要的一切。这个实现有点快而且脏,所以它可能不适用于同时下载或多线程使用;严重性代码说明“DownloadProgressTracker.DownloadProgress”不包含接受3个参数的构造函数。必须明确,DownloadProgressTracker.DownloadProgress是因为我创建了一个新类。我调用了新类DownloadProgressTracker,助手是DownloadProgressTracker。@DanielHalmoni我刚刚意识到我从两个不同版本复制了代码。更新后的代码应该可以工作。它似乎工作得很好。我将progressBar的行更改为(int),如果没有,则将其强制转换为(int)。我得到的错误是无法将double转换为int.pBarFileProgress.Value=(int)tracker.GetProgress()*100;另一个小问题是,progressBar在更新标签1和2之后,似乎立即从0更新到100。我想知道是否有可能使progressBar与标签一起实时更新?但它工作正常。将
*100
放在括号
(int)(tracker.GetProgress()*100.0)
中。否则,它会先将进度(0到1)转换为int,然后再乘以100,因此只能得到0或100。
//Somewhere in your constructor / initializer:
tracker = new DownloadProgressTracker(50, TimeSpan.FromMilliseconds(500));

void client_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    tracker.SetProgress(e.BytesReceived, e.TotalBytesToReceive);
    pBarFileProgress.Value = tracker.GetProgress() * 100;
    label1.Text = e.BytesReceived + "/" + e.TotalBytesToReceive;
    label2.Text = tracker.GetBytesPerSecondString();
}
tracker.NewFile();