什么是跟踪ReadAsStreamAsync下载速率的有效方法

时间:2014-04-01 19:41:25

标签: c# async-await

我在一些真实世界的例子中学习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));

我得到的结果如下:

enter image description here

我担心我的代码出了问题,因为对于下载速度计算,我的速度从81到8192 kpbs。 在我的异步任务示例中,我使用了从Measure data transfer rate over tcp using c#

获取的下载速率计数方法

我在代码中做错了什么?

1 个答案:

答案 0 :(得分:3)

您的代码没有任何问题,而是显示数据的期望

从单一间隔的即时值变为长时间的平均值(整个下载/持续1-3-10秒)以获得您期望的表示。