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();
}
现在我添加了这个方法
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;
}
我想使用此方法或其他方法在label2上的progresschanged事件中显示下载速度。但我不确定如何使用这种方法。
不确定如何在progresschanged事件中使用它。
答案 0 :(得分:1)
对您准备好的方法<xpath expr="//table[contains(@class, 'table-condensed')]/tr[first()]/td[first()]" position="replace">
<!-- YOUR XML HERE -->
</xpath>
的调用最适合progressChanged
,如下所示:
client_DownloadProgressChanged
但是,您必须使用progressChanged(e.BytesReceived);
代替TotalSeconds
,否则值将无法正确并导致除零异常
Seconds
此帮助程序类将跟踪收到的块,时间戳和进度:
var bytesPerSecond = bytesChange / timeSpan.TotalSeconds;
在以下示例中,进度跟踪器将为您提供上次public class DownloadProgressTracker
{
private long _totalFileSize;
private readonly int _sampleSize;
private readonly TimeSpan _valueDelay;
private DateTime _lastUpdateCalculated;
private long _previousProgress;
private double _cachedSpeed;
private Queue<Tuple<DateTime, long>> _changes = new Queue<Tuple<DateTime, long>>();
public DownloadProgressTracker(int sampleSize, TimeSpan valueDelay)
{
_lastUpdateCalculated = DateTime.Now;
_sampleSize = sampleSize;
_valueDelay = valueDelay;
}
public void NewFile()
{
_previousProgress = 0;
}
public void SetProgress(long bytesReceived, long totalBytesToReceive)
{
_totalFileSize = totalBytesToReceive;
long diff = bytesReceived - _previousProgress;
if (diff <= 0)
return;
_previousProgress = bytesReceived;
_changes.Enqueue(new Tuple<DateTime, long>(DateTime.Now, diff));
while (_changes.Count > _sampleSize)
_changes.Dequeue();
}
public double GetProgress()
{
return _previousProgress / (double) _totalFileSize;
}
public string GetProgressString()
{
return String.Format("{0:P0}", GetProgress());
}
public string GetBytesPerSecondString()
{
double speed = GetBytesPerSecond();
var prefix = new[] { "", "K", "M", "G"};
int index = 0;
while (speed > 1024 && index < prefix.Length - 1)
{
speed /= 1024;
index++;
}
int intLen = ((int) speed).ToString().Length;
int decimals = 3 - intLen;
if (decimals < 0)
decimals = 0;
string format = String.Format("{{0:F{0}}}", decimals) + "{1}B/s";
return String.Format(format, speed, prefix[index]);
}
public double GetBytesPerSecond()
{
if (DateTime.Now >= _lastUpdateCalculated + _valueDelay)
{
_lastUpdateCalculated = DateTime.Now;
_cachedSpeed = GetRateInternal();
}
return _cachedSpeed;
}
private double GetRateInternal()
{
if (_changes.Count == 0)
return 0;
TimeSpan timespan = _changes.Last().Item1 - _changes.First().Item1;
long bytes = _changes.Sum(t => t.Item2);
double rate = bytes / timespan.TotalSeconds;
if (double.IsInfinity(rate) || double.IsNaN(rate))
return 0;
return rate;
}
}
收到的数据包的平均下载速率,但只有50
毫秒(因此用户界面不会闪烁)。您可能需要稍微修改一下这些值,以便在准确性和平滑度之间找到一个良好的平衡。
500
请注意,您必须在每个新文件之前或之后重置跟踪器:
//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();
}
如果你需要一些更大的文件来测试它,我发现了一些here