最近,我在.Net 4.5.1上使用HttpClients.PostAsync时遇到了性能问题。最初服务器(Owin + WebApi)在发送之前缓冲响应。这导致巨大的内存使用开销(序列化响应大小> 1Gb)。在我打开服务器上的响应流后,客户端字面上停止工作。事实证明,当从服务器读取响应时,原因是客户端上的缓冲区重新分配。我检查了HttpClient实现,并在void MyTreeView::mouseReleaseEvent(QMouseEvent *e) {
if (e->button() == Qt::RightButton) {
QTreeWidgetItem *item = itemAt(e->pos());
if (item) {
QMenu m;
m.addAction("hello");
m.addAction("world");
QAction *selected = m.exec(mapToGlobal(e->pos()));
if (selected) {
qDebug() << "selected" << selected->text();
}
}
} else {
QTreeView::mouseReleaseEvent(e);
}
}
方法中找到了这个有趣的部分:
HttpClient.SendAsync
因此当if (result.Content == null || completionOption == HttpCompletionOption.ResponseHeadersRead)
{
this.SetTaskCompleted(request, linkedCts, tcs, result);
}
else
{
this.StartContentBuffering(request, linkedCts, tcs, result);
}
不是completionOption
时,始终会缓冲响应。根据{{3}} SendAsync的实现与意图一致。
现在,当ResponseHeadersRead
实现发送PostAsync
时,响应流始终在POST上缓冲。所以问题是为什么PostAsync必须等待(和缓冲)整个响应才能在处理继续之前到达?
答案 0 :(得分:7)
有明显的部分 - 如果你没有指定HttpCompletionOption.ResponseHeadersRead
,Task
只会在读取整个回复时完成;你必须在此期间将响应数据存储在某处。
为什么PostAsync
不允许您指定HttpCompletionOption.ResponseHeadersRead
?可能是因为大多数时候它并不是那么有用。 POST
用于发布数据,而不是用于检索数据 - 这是GET
的工作。 HttpClient
是围绕WebAPI和“REST”服务设计的,并正确使用了HTTP动词。
如果您需要使用POST
来检索如此大量的数据,您有两个基本选项:
SendAsync
HttpClient
(HttpWebRequest
稍微复杂一点,但会给你更多控制权)