C# 为什么HttpClient.PostAsync缓冲区会响应?

C# 为什么HttpClient.PostAsync缓冲区会响应?,c#,httpclient,C#,Httpclient,最近,我在.Net 4.5.1上使用HttpClients.PostAsync时遇到了性能问题。最初,服务器(Owin+WebApi)在发送之前正在缓冲响应。这导致了巨大的内存使用开销(序列化响应大小>1Gb)。在我打开服务器上的响应流之后,客户端实际上停止了工作。事实证明,原因是从服务器读取响应时客户端上的缓冲区重新分配。我检查了HttpClient实现,并在HttpClient.SendAsync方法中找到了这个有趣的部分: if (result.Content == null || com

最近,我在.Net 4.5.1上使用HttpClients.PostAsync时遇到了性能问题。最初,服务器(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的实现目的是一致的


现在,由于实现了
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发生了变化。谢谢