我在一些真实世界的例子中学习C#5异步/等待 - 从网上保存文件并显示下载速度。
有一种我担心的方法是错误的,特别是在下载速度计算方面。
public async Task DownloadAsyncDemo(Uri requestUri, IProgress<string> progress, CancellationToken cancellationToken)
{
var downloadedFileName = "file";
var downloadDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "TmpDownload");
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
{
using (var responseMessage = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false))
{
if (responseMessage.Content.Headers.ContentDisposition != null)
downloadedFileName = responseMessage.Content.Headers.ContentDisposition.FileName;
else
downloadedFileName = Path.GetFileName(requestUri.LocalPath);
downloadedFileName = Path.Combine(downloadDirectory, downloadedFileName);
if (!Directory.Exists(downloadDirectory))
Directory.CreateDirectory(downloadDirectory);
int bufferSize = 1024; // 1 KB buffer
using (var httpStream = await responseMessage.Content.ReadAsStreamAsync().ConfigureAwait(false))
{
using (var filestream = new FileStream(downloadedFileName, FileMode.Create, FileAccess.Write, FileShare.None, 4084, true))
{
//await httpStream.CopyToAsync(filestream); // need more low level logic below
Stopwatch sw = new Stopwatch();
byte[] buffer = new byte[bufferSize];
while (true)
{
sw.Reset();
sw.Start();
int num = await httpStream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);
sw.Stop();
if (sw.ElapsedMilliseconds > 0)
progress.Report(string.Format("Time taken: {0} ms Data size: {1} KB Speed: {2} kbps", sw.ElapsedMilliseconds, num, num * 8 / sw.ElapsedMilliseconds));
int bytesRead;
if ((bytesRead = num) != 0)
await filestream.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
else
break;
}
}
}
}
}
}
}
我按照以下方式运行:
var dManger = DownloadManager.Instance;
var cancelationToken = new CancellationToken();
Task.Run(() => dManger.DownloadAsyncDemo(new Uri("http://speedtest.tokyo.linode.com/100MB-tokyo.bin")
, new Progress<string>(data => Console.WriteLine(data)), cancelationToken));
我得到的结果如下:
我担心我的代码出了问题,因为对于下载速度计算,我的速度从81到8192 kpbs。 在我的异步任务示例中,我使用了从Measure data transfer rate over tcp using c#
获取的下载速率计数方法我在代码中做错了什么?
答案 0 :(得分:3)
您的代码没有任何问题,而是显示数据的期望。
从单一间隔的即时值变为长时间的平均值(整个下载/持续1-3-10秒)以获得您期望的表示。