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