Недавно я столкнулся с проблемами производительности при использовании HttpClients.PostAsync на .Net 4.5.1. Первоначально сервер (Owin + WebApi) представлял буферную реакцию перед отправкой. Это вызвало огромные издержки использования памяти (размер сериализованного ответа составляет> 1 Гбит). После того, как я включил поток ответов на сервере, клиент буквально прекратил работать. Оказалось, что причиной было перераспределение буфера на клиенте при чтении ответа с сервера. Я проверил HttpClient реализации и нашел интересную часть в HttpClient.SendAsync
методе:Зачем нужен буфер HttpClient.PostAsync?
if (result.Content == null || completionOption == HttpCompletionOption.ResponseHeadersRead)
{
this.SetTaskCompleted(request, linkedCts, tcs, result);
}
else
{
this.StartContentBuffering(request, linkedCts, tcs, result);
}
Так что, когда completionOption
не ResponseHeadersRead
ответа всегда буферизации. Согласно SendAsync documentation реализация SendAsync согласуется с намерением.
Теперь, когда PostAsync
реализована отправка ResponseContentRead
, поток ответа всегда буферизуется POST. Поэтому вопрос в том, почему PostAsync должен ждать (и буфер) для полного ответа, чтобы прибыть до продолжения обработки?
Я должен использовать POST, потому что мой объект запроса «не подходит» в методе GET. В любом случае я изменил реализацию на явный вызов SendAsync – koruyucu
@koruyucu Да, это может быть сложно. Обычный способ решить этот REST-полностью будет заключаться в использовании, например, 'PUT', чтобы направить ваш объект запроса на сервер, который вернет вам URL-адрес« GET », чтобы получить ответ. Но это, вероятно, создаст больше проблем, чем решает: D – Luaan
@ Luaan, потому что он решит * ничего *, чтобы быть ясным :) – usr