2016-04-05 10 views
0

アプリ内で任意のファイルのダウンロード状況を提供する必要があります。 私はHttpClient.GetInputStreamAsyncの進歩を使うことができると思ったが、それは細粒ではなかった。進行通知は非常にまれです。以下のコード:WindowsストアアプリHttpClientの進捗状況

var httpClient = new HttpClient(); 
var path = new Uri(@"http://<path>"); 

using (var inputStream = (await httpClient.GetInputStreamAsync(path).AsTask(new MyProgress())).AsStreamForRead()) 
{ 
    var outputFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("output.mov", CreationCollisionOption.ReplaceExisting); 

    using (var outputStream = (await outputFile.OpenAsync(FileAccessMode.ReadWrite)).AsStreamForWrite()) 
    { 
     await inputStream.CopyToAsync(outputStream); 

     await outputStream.FlushAsync(); 
    } 
} 

Debug.WriteLine("done"); 


private class MyProgress : IProgress<HttpProgress> 
{ 
    public void Report(HttpProgress value) 
    { 
     Debug.WriteLine("HTTP {0} progress {1}/{2}", value.Stage, value.BytesReceived, value.TotalBytesToReceive); 
    } 
} 

出力:

HTTP ResolvingName progress 0/ 
HTTP ConnectingToServer progress 0/ 
HTTP SendingHeaders progress 0/ 
HTTP WaitingForResponse progress 0/ 
HTTP ReceivingHeaders progress 0/ 
HTTP ReceivingContent progress 0/109192147 
done 

ので、時間のある時点での総バイト数を受け取るためには、知られているが、何の進展は、ファイルのダウンロード中に報告されていません。

答えて

0

HttpClient.GetInputStreamAsyncは、ファイルのダウンロード中に進行状況をサポートしていないので、あなたは【選択次のコードは、HttpClient.GetAsyncを使用するようにコードを更新しているようにGetAsyncGetBufferAsyncなどHttpClientの他の方法を使用することができます。

var httpClient = new HttpClient(); 
    var path = new Uri("https://sec.ch9.ms/slides/developerGuideToWindows10/02-XAMLcontrols.pptx"); 
    HttpResponseMessage response = await httpClient.GetAsync(path).AsTask(new MyProgress()); 
    using (Stream responseStream = (await response.Content.ReadAsInputStreamAsync()).AsStreamForRead()) 
    { 
     var outputFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("output.pptx", CreationCollisionOption.ReplaceExisting); 
     using (var outputStream = (await outputFile.OpenAsync(FileAccessMode.ReadWrite)).AsStreamForWrite()) 
     { 
      await responseStream.CopyToAsync(outputStream); 
      await outputStream.FlushAsync(); 
     } 
    } 
    Debug.WriteLine("done"); 

そして、私は以下のようなソリューションになってしまった出力

enter image description here

+0

それは、進捗状況を報告し、しかしそれはまた、あるメモリにすべてのコンテンツをロード私が避けたいもの。遅く答えて申し訳ありません、忙しかったです。 – aguyngueran

0

var httpClient = new HttpClient(); 

var path = new Uri(@"http://<path>"); 

var progressHelper = new ProgressHelper(); 

using (var inputStream = (await httpClient.GetInputStreamAsync(path).AsTask(progressHelper)).AsStreamForRead()) 
{ 
    var outputFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("output.mov", CreationCollisionOption.ReplaceExisting); 

    using (var outputStream = (await outputFile.OpenAsync(FileAccessMode.ReadWrite)).AsStreamForWrite()) 
    { 
     var buffer = new byte[1024 * 1024]; 
     int read; 

     while ((read = await inputStream.ReadAsync(buffer, 0, buffer.Length)) > 0) 
     { 
      progressHelper.BytesReceived += (ulong)read; 

      await outputStream.WriteAsync(buffer, 0, read); 
     } 

     await outputStream.FlushAsync(); 
    } 
} 

Debug.WriteLine("done"); 


private class ProgressHelper : IProgress<HttpProgress> 
{ 
    private ulong _bytesReceived = 0; 
    private ulong? _totalBytesToReceive = null; 

    public void Report(HttpProgress value) 
    { 
     Debug.WriteLine("HTTP {0} progress {1}/{2}", value.Stage, value.BytesReceived, value.TotalBytesToReceive); 

     TotalBytesToReceive = value.TotalBytesToReceive;     
    } 

    public ulong? TotalBytesToReceive 
    { 
     get 
     { 
      return _totalBytesToReceive; 
     } 
     set 
     { 
      if (_totalBytesToReceive == value) 
       return; 

      _totalBytesToReceive = value; 
      UpdateProgress(); 
     } 
    } 

    public ulong BytesReceived 
    { 
     get 
     { 
      return _bytesReceived; 
     } 
     set 
     { 
      if (_bytesReceived == value) 
       return; 

      _bytesReceived = value; 
      UpdateProgress(); 
     } 
    } 

    public int? Progress 
    { 
     get 
     { 
      if (_totalBytesToReceive.HasValue) 
      { 
       return (int)Math.Round((100.0 * _bytesReceived)/_totalBytesToReceive.Value); 
      } 

      return null; 
     } 
    } 

    private void UpdateProgress() 
    { 
     Debug.WriteLine("Progress: {0}", Progress); 
    } 
} 
+0

あなた自身が新しいバッファを作成しました。このコードは、メモリから空き領域をメモリに、ダウンロードバッファとしてメモリ内に適用します。それでもメモリを消費します。あなたが書いたものは、HttpClient APIによって包まれているだけです –

関連する問題