在内容完成100%之前从HttpResponseMessage读取标头 [英] Read headers from HttpResponseMessage before Content is 100% complete

查看:86
本文介绍了在内容完成100%之前从HttpResponseMessage读取标头的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


  1. 在整个响应流回之前,如何访问响应头?

  2. 如何在流到达时读取流?? li>
  3. 对于这样的接收HTTP响应的精细控制,HttpClient是我的最佳选择吗?

可能说明了我的问题:

using (var response = await _httpClient.SendAsync(request,
  HttpCompletionOption.ResponseHeadersRead))
{
   var streamTask = response.Content.ReadAsStreamAsync();
   //how do I check if headers portion has completed? 
   //Does HttpCompletionOption.ResponseHeadersRead guarantee that?
   //pseudocode
   while (!(all headers have been received)) 
     //maybe await a Delay here to let Headers get fully populated
   access_headers_without_causing_entire_response_to_be_received

   //how do I access the response, without causing an await until contents downloaded?
   //pseudocode
   while (stremTask.Resul.?) //i.e. while something is still streaming
     //? what goes here? a chunk-read into a buffer? or line-by-line since it's http?
   ...



编辑为我澄清另一个灰色区域:

我发掘出的任何参考文献都有某种阻塞性陈述,这将导致等待内容到达。我阅读的参考文献通常不访问streamTask.Result或Content上的方法或属性,并且我不知道在streamTask进行时是否可以引用哪些引用,而在任务完成之前将哪些引用等待。 / p>


Edit to clarify another gray area for me:
Any reference I unearthed has some kind of a blocking statement, that would cause await for the contents to arrive. References I read usually access methods or properties on the streamTask.Result or on the Content, and I don't know enough to rule out which such references are okay as the streamTask is progressing vs. which are going to cause an await until the task completes.

推荐答案

根据我自己的测试,直到开始阅读内容流并且您是正确的,内容才可以传输调用 Task.Result 是一个阻塞调用,但是它的本质是同步点。 但是,它不会阻塞对整个内容进行预缓冲,只会阻塞直到内容开始来自服务器。

Based on my own testing, the content won't be transferred until you start reading the content stream, and you're correct that calling Task.Result is a blocking call, but its very nature, it's a synchronisation point. But, it doesn't block to pre-buffer the entire content, it only blocks until the content starts to come from the server.

因此,无限流将不会无限期地阻塞。因此,尝试异步获取流可能被认为是过大的,尤其是在标头处理操作相对较短的情况下。但是,如果需要,您可以始终在处理其他任务的内容流时处理标头。

So an infinite stream won't block for an infinite amount of time. As such, trying to fetch the stream asynchronously might be deemed overkill, especially if your header processing operation is relatively short. But if you want to, you can always process the headers while the content stream is being handled on another task. Something like this would accomplish that.

static void Main(string[] args)
{
    var url = "http://somesite.com/bigdownloadfile.zip";
    var client = new HttpClient();
    var request = new HttpRequestMessage(HttpMethod.Get, url);

    var getTask = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
    Task contentDownloadTask = null;

    var continuation = getTask.ContinueWith((t) =>
    {
        contentDownloadTask = Task.Run(() =>
        {
            var resultStream = t.Result.Content.ReadAsStreamAsync().Result;
            resultStream.CopyTo(File.Create("output.dat"));
        });

        Console.WriteLine("Got {0} headers", t.Result.Headers.Count());
        Console.WriteLine("Blocking after fetching headers, press any key to continue...");
        Console.ReadKey(true);
    });

    continuation.Wait();
    contentDownloadTask.Wait();
    Console.WriteLine("Finished downloading {0} bytes", new FileInfo("output.dat").Length);

    Console.WriteLine("Finished, press any key to exit");
    Console.ReadKey(true);
}

请注意,无需检查标题部分是否完整,您可以ve使用 HttpCompletionOption.ResponseHeadersRead 选项明确指定了该选项。 SendAsync 任务在检索到标头之前不会继续。

Note that there's no need to check if the headers portion is complete, you've explicitly specified that with the HttpCompletionOption.ResponseHeadersRead option. The SendAsync task will not continue until the headers have been retrieved.

这篇关于在内容完成100%之前从HttpResponseMessage读取标头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆