为什么HttpClient.PostAsync缓冲区响应
本文关键字:响应 缓冲区 PostAsync HttpClient 为什么 | 更新日期: 2023-09-27 17:50:48
最近我在使用httpclient时遇到了性能问题。PostAsync在。net 4.5.1。最初服务器(Owin + WebApi)在发送之前缓冲响应。这会导致巨大的内存使用开销(序列化响应大小大于1Gb)。在我打开响应流后,服务器客户端实际上停止了工作。原因是客户端在读取服务器响应时重新分配了缓冲区。我检查了HttpClient实现,并在HttpClient.SendAsync
方法中发现了这个有趣的部分:
if (result.Content == null || completionOption == HttpCompletionOption.ResponseHeadersRead)
{
this.SetTaskCompleted(request, linkedCts, tcs, result);
}
else
{
this.StartContentBuffering(request, linkedCts, tcs, result);
}
所以当completionOption
不是ResponseHeadersRead
时,响应总是缓冲的。根据SendAsync文档,SendAsync的实现与意图一致。
现在,由于PostAsync
被实现发送ResponseContentRead
,响应流总是在post上缓冲。所以问题是为什么PostAsync必须等待(和缓冲)整个响应到达处理继续之前?
有一个明显的部分-如果您不指定HttpCompletionOption.ResponseHeadersRead
, Task
将只在读取整个响应时完成;同时,您必须将响应数据存储在某处。
为什么PostAsync
不允许指定HttpCompletionOption.ResponseHeadersRead
?可能是因为大多数时候,它并不是那么有用。POST
用于发布数据,而不是检索数据——这是GET
的工作。HttpClient
是围绕webapi和"REST"服务设计的,并适当使用了HTTP动词。
如果您需要使用POST
来检索如此大量的数据,您有两个基本选项:
- 使用
SendAsync
- 不要使用
HttpClient
(HttpWebRequest
有点复杂,但给你更多的控制方式)