最近我在.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);
}
Run Code Online (Sandbox Code Playgroud)
所以什么时候completionOption不ResponseHeadersRead响应总是缓冲.根据SendAsync文档,SendAsync的实现与意图一致.
现在,正如PostAsync实现发送一样ResponseContentRead,响应流总是在POST上缓冲.所以问题是为什么PostAsync必须等待(和缓冲)整个响应才能在处理继续之前到达?
有明显的部分 - 如果你没有指定HttpCompletionOption.ResponseHeadersRead,Task只有在读取整个响应时才会完成; 你必须在此期间将响应数据存储在某个地方.
为什么PostAsync不允许你指定HttpCompletionOption.ResponseHeadersRead?可能是因为大多数时候它并不是那么有用.POST用于发布数据,而不是用于检索数据 - 这GET是工作.HttpClient是围绕WebAPI和"REST"服务设计的,正确使用了HTTP动词.
如果您需要使用POST来检索如此大量的数据,您有两个基本选项:
SendAsyncHttpClient(HttpWebRequest有点复杂,但给你更多的控制)| 归档时间: |
|
| 查看次数: |
2393 次 |
| 最近记录: |