2017-06-06 3 views
1

は、低レベルHttpWebRequestクラスとその同類は廃止されている、とthe official recommendationSystem.Net.Http.HttpClientHttpClientを使用してリモートリソース全体をダウンロードしないようにしますか? UWPの下

を使用することですしかし、明白な監督やHttpClient実装のバグのいずれかがあるように思われる:APIレスポンスストリームのレイジー評価を可能にするためにリモートリソース全体を自動的にダウンロードしないリモートURIへのリクエストを行う方法を提供していないようです(GETリクエストの場合)。

The documentation for the HttpClient.GetAsync() methodは言う:

この操作はブロックされません。返されたタスクオブジェクトは、全体の応答(コンテンツを含む)が読み取られた後に完了します。

これは、要求が完了したとみなされる前にリモートリソース全体がダウンロードされることを前提としています。

操作が応答が利用可能であり、ヘッダが読み込まれるとすぐに完了する必要があり、次のようにそれが文書化されているとして指定され、理論的にこの場合HttpCompletionOption.ResponseHeadersRead回避作業を可能にするHttpCompletionOptionパラメータが、あります。内容はまだ読み込まれていません。 HttpCompletionOptionが指定されているにかかわらず、そのしかし

は、すべてのケースでは、HttpClient.GetAsync()は(チェックを任意の制限なし!すべてを一度に!メモリに!)レスポンスの完全なContentLengthバイトを割り当てるためのプロセスに表示されます。もちろん、それはやや狂気で、本当の問題です。

私の特別なケースでは、http範囲ヘッダーをサポートしていないサーバーからマルチギガバイトのリモートリソースの最初の数kbを読み取るだけです。これは通常「汗なし」の操作です。ウェブリクエストを作成し、満足するまでレスポンスストリームから読み込み、レスポンスを閉じて気分転換してください。

デフォルトのHttpClient APIではオプションではないようです。 rawソケットを使用して自分のHTTPリクエストを作成することを含まない簡単な回避策はありますか?すべての場合において

答えて

1

、HttpClient.GetAsync()レスポンスの完全ん。ContentLengthバイトを割り当てるように表示されます(メモリーに!すべてを一度に!チェックの任意の制限なし!)

これは当てはまりませんHttpCompletionOption.ResponseHeadersReadオプション

古い甘いHttpWebRequestクラスのように、レスポンスストリームを開き、数バイトを読み取り、応答を破棄することができます。ここにはan exampleです。ここで

は私の実験である:(私が代わりにWindows.Web.Http.HttpClientを使用しますが、System.Net.Http.HttpClientが同様のAPIを提供)

private HttpClient httpClient = new HttpClient(); 
private CancellationTokenSource cts = new CancellationTokenSource(); 


private async void MainPage_Loaded(object sender, RoutedEventArgs e) 
{ 
    Uri resourceAddress = new Uri("http://somewhere/gigabyte.zip"); 

    try 
    { 
     HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, resourceAddress); 

     // Do not buffer the response. 
     HttpResponseMessage response = await httpClient.SendRequestAsync(
      request, 
      HttpCompletionOption.ResponseHeadersRead).AsTask(cts.Token); 

     using (Stream responseStream = (await response.Content.ReadAsInputStreamAsync()).AsStreamForRead()) 
     { 
      int read = 0; 
      byte[] responseBytes = new byte[1000]; 
      do 
      { 
       read = await responseStream.ReadAsync(responseBytes, 0, responseBytes.Length); 
       break; 
      } while (read != 0); 
     }     
    } 
    catch (TaskCanceledException) 
    {     
    } 
    catch (Exception ex) 
    { 
    } 
    finally 
    { 
    } 
} 
+0

私のテストケースがborkedたようだとしませんでした'HttpCompletionOptions'値を確実にシミュレートします。 –

関連する問題