2013-10-06 3 views
1

Я пытаюсь получить текущую скорость загрузки в WebClient загрузку файла, однако, когда я использую формулу, я уверен, что должен работать:WebClient DownloadDataAsync тока скорость загрузки

Stopwatch.Stop(); 
double msElapsed = Stopwatch.Elapsed.TotalMilliseconds; 
int bytesDownloaded = (int)e.BytesReceived - lastBytesDownloaded; 
double downloadSpeed = (double)bytesDownloaded/(msElapsed/1000); 
lastBytesDownloaded = (int)e.BytesReceived; 
Stopwatch.Restart(); 

Где Секундомер это секундомер, который я начал, когда я начал загрузку файла, lastBytesDownloaded - это переменная класса, и все это находится внутри события downloadProgressChanged, однако скорость загрузки сильно отличается от того, что на самом деле происходит.

Например, если бы я загружал файл со скоростью 500 кбит/с, он бы быстро перескакивал с (например) 10 кбит/с до 50 МБ/с полностью случайным образом.

я могу получить точное среднее время загрузки, сделав пару редактирует в том, что:

double sElapsed = Stopwatch.Elapsed.TotalSeconds; 
int bytesDownloaded = (int)e.BytesReceived; 
double downloadSpeed = bytesDownloaded/sElapsed; 

Но это не то, что я хочу. Как я могу получить более стабильное значение для current скачать скорость?

+0

Вы хотите сделать скользящее среднее, Rx.NET это действительно хороший способ сделать это. PS Спасибо за этот пример, который мне придется украсть для разговора RxJS в следующем месяце: P [Посмотрите этот пример.] (Http://stackoverflow.com/questions/14805392/rx-stateful-transform-of-sequence- eg-exponential-moving-average) – Aron

ответ

2

Вам нужно всего лишь smooth данные в течение более длительного периода времени. Например, не сообщайте текущую скорость загрузки только на основе последнего измерения; используйте вместо него (возможно, weighted) moving average.

Мертвый простой пример:

var measurements = 0, maxDataPoints = 5; 
var dataPoints = new double[maxDataPoints]; 

И потом:

Stopwatch.Stop(); 
double msElapsed = Stopwatch.Elapsed.TotalMilliseconds; 
int bytesDownloaded = (int)e.BytesReceived - lastBytesDownloaded; 
lastBytesDownloaded = (int)e.BytesReceived; 
double dataPoint = (double)bytesDownloaded/(msElapsed/1000); 
dataPoints[measurements++ % maxDataPoints] = dataPoint; 

double downloadSpeed = dataPoints.Average(); 
Stopwatch.Restart(); 
+0

Это замечательно, как и другие ухищрения пары, которые я сделал (иногда часы будут сообщать <1 мс, я просто использовал Math.Max ​​для установки нижней границы), это сработало довольно хорошо. Есть ли какие-либо максимальные точки данных или другие вещи, которые вы можете предложить сделать более последовательными? – Ipquarx

Смежные вопросы