使用HttpClient从ASP.NET WebApi异步读取分块内容

16

我希望使用HttpClient异步读取分块(指HTTP 1.1分块传输编码)内容。

我正在查看HttpContent异步方法: MSDN链接

然而,在返回的字节数组任务的情况下,例如:

  

在所有内容被写入字节数组之后,返回的Task对象将完成

我正在精确地获取分块内容,因为服务器不知道何时可用所有数据,因此我不知道何时将到达所有内容。与其等待任务完成(可能需要数小时),我想能够读取到chunks到达时的内容。

我是否可以读取响应内容的一部分,例如:有一些任务在收到响应中的每4K字节内容时完成?

在这种情况下,使用HttpClient是否有优势?

2个回答

23

使用 HttpClient.SendAsync 方法时,你可以传递 HttpCompletionOption 参数来告诉 HttpClient 不要为你缓存响应,并在获取到头部后立即返回。然后你可以使用 ReadAsStreamAsync 方法来获取一个流,该流将允许你在数据到达时获取它们。


工作得非常好。我使用了HttpSelfHostServer,并确保内容被分块。我可以在客户端以块的形式跟踪其到达。无需手动解析分块内容 - 流已经在传输编码方面进行了去块处理,即使数据以块的形式可用。 - Tony

0

这里有一个完整的示例,说明如何下载文件而不将其内容读入内存。非常好用。

static async Task HttpGetForLargeFileInRightWay()
{
    using (HttpClient client = new HttpClient())
    {
        const string url = 
"https://github.com/tugberkugurlu/ASPNETWebAPISamples/archive/master.zip";
        using (HttpResponseMessage response = await client.GetAsync(url, 
HttpCompletionOption.ResponseHeadersRead))
        using (Stream streamToReadFrom = await response.Content.ReadAsStreamAsync())
        {
            string fileToWriteTo = Path.GetTempFileName();
            using (Stream streamToWriteTo = File.Open(fileToWriteTo, FileMode.Create))
            {
                await streamToReadFrom.CopyToAsync(streamToWriteTo);
            }
        }
    }
}

或者,您可以使用StreamReader读取流,而不是使用CopyToAsync()

using (var stream = await response.Content.ReadAsStreamAsync())
using (var reader = new StreamReader(stream))
{
    int bytesCount = 100;
    var buffer = new char[bytesCount];
    reader.ReadBlock(buffer, 0, bytesCount);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接