C# 为什么HttpClient.PostAsync缓冲区会响应?
最近,我在.Net 4.5.1上使用HttpClients.PostAsync时遇到了性能问题。最初,服务器(Owin+WebApi)在发送之前正在缓冲响应。这导致了巨大的内存使用开销(序列化响应大小>1Gb)。在我打开服务器上的响应流之后,客户端实际上停止了工作。事实证明,原因是从服务器读取响应时客户端上的缓冲区重新分配。我检查了HttpClient实现,并在C# 为什么HttpClient.PostAsync缓冲区会响应?,c#,httpclient,C#,Httpclient,最近,我在.Net 4.5.1上使用HttpClients.PostAsync时遇到了性能问题。最初,服务器(Owin+WebApi)在发送之前正在缓冲响应。这导致了巨大的内存使用开销(序列化响应大小>1Gb)。在我打开服务器上的响应流之后,客户端实际上停止了工作。事实证明,原因是从服务器读取响应时客户端上的缓冲区重新分配。我检查了HttpClient实现,并在HttpClient.SendAsync方法中找到了这个有趣的部分: if (result.Content == null || com
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的实现目的是一致的
现在,由于实现了
PostAsync
发送ResponseContentRead
,所以响应流总是在POST上缓冲。所以问题是,为什么PostAsync必须等待(和缓冲区)整个响应到达,然后才能继续处理?有一个明显的部分-如果您不指定HttpCompletionOption.ResponseHeadersRead
,则只有在读取整个响应时,任务才会完成;同时,您必须将响应数据存储在某个位置
为什么PostAsync
不允许您指定HttpCompletionOption.ResponseHeadersRead
?可能是因为它在大多数情况下并不是那么有用POST
用于发布数据,而不是检索数据-这是GET
的工作HttpClient
是围绕webapi和“REST”服务设计的,并正确使用了HTTP动词
如果需要使用POST
检索如此大量的数据,您有两个基本选项:
- 使用
SendAsync
- 不要使用
HttpClient
(HttpWebRequest
稍微复杂一点,但会给您更多的控制权)
我必须使用POST,因为我的请求对象“不适合”GET方法。无论如何,我将实现更改为显式调用SendAsync@koruyucu是的,这可能很棘手。完全解决此REST的通常方法是使用例如PUT
将请求对象推送到服务器,这将返回一个URL到GET
,以检索响应。但这可能会带来比解决问题更多的麻烦:D@Luaan因为它无法解决任何问题,很明显:)它会排除某些超时,但不会排除初始请求负载,也不会排除最终响应负载。嗨@koruyucu,我想使用HttpClient调用SOAP web服务,因此,我不会使用PostAsync
发送请求,我想知道使用SendAsync
是否适合您?我这样问是因为自2015年以来,HttpClient发生了变化。谢谢