2014-04-01 1 views
0

일부 실제 사례에서 C# 5 async/await을 배우고 있습니다. 웹에서 다운로드 속도 속도를 표시하여 파일을 저장합니다.ReadAsStreamAsync 다운로드 속도를 추적하는 유효한 방법은 무엇입니까

내가 잘못 생각하는 방법이 있는데, 특히 다운로드 속도 계산이 잘못되었습니다.

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#

코드에서 잘못된 것은 무엇입니까?

답변

3

코드에 아무런 문제가 없지만 데이터를 표시하는 데이라는 이 필요합니다.

예상되는 표현을 얻기 위해 단일 간격을 기준으로 한 순간 값에서 장기간 평균 (전체 다운로드/마지막 1-3-10 초)으로 변경하십시오.

+0

감사합니다. 알렉세이, 예를 들어 매초마다 좋은 방법을 제안 해 주시겠습니까? 나는 Timer 또는 Task.Deley가 여기에 필요하다고 생각하지만 비동기 작업에서 평균 다운로드 속도를 얻는 방법을 잘 모르겠습니다. – Zelid

+1

나는 맹목적으로 {time, block size} 값을 배열에 추가하고'.SkipWhile (item => item.timeFromStartMs item.BlockSize)'와 같은 일을한다. (다운로드가 정말 큰 경우 전체 역사에서 선형 검색보다 나은 것을 필요로합니다) –

관련 문제