Мы перенесли проект из WCF в Web API (SelfHost), и во время процесса мы заметили огромный спад при обслуживании веб-приложения. Теперь 40-50 секунд против 3 секунд ранее.ASP.NET Web API 2 - StreamContent чрезвычайно медленный
Я воспроизвести проблему в простой консольного приложения, добавляя различные NuGet Pacakges для AspNet.WebApi и OwinSelfHost со следующим контроллером:
var stream = new MemoryStream();
using (var file = File.OpenRead(filename))
{
file.CopyTo(stream);
}
stream.Position = 0;
var response = Request.CreateResponse(System.Net.HttpStatusCode.OK);
/// THIS IS FAST
response.Content = new ByteArrayContent(stream.ToArray());
/// THIS IS SLOW
response.Content = new StreamContent(stream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue(System.Web.MimeMapping.GetMimeMapping(filename));
response.Content.Headers.ContentLength = stream.Length;
Как вы можете видеть из кода той лишь разницей, использование StreamContent (slooooow) и ByteArrayContent.
Приложение размещено на машине Win10 и доступно с моего ноутбука. Fiddler показывает, что для получения одного 1 МБ-файла с сервера на мой ноутбук с помощью StreamContent требуется 14 секунд, а ByteArrayContent - менее 1 с.
Также обратите внимание, что полный файл считывается в память, чтобы показать, что единственным отличием является класс содержимого.
Странная вещь, что кажется, что ее передача сама по себе медленная. Сервер отвечает заголовкам быстро/немедленно, но данные занимает много времени, чтобы прийти, как показано на Скрипач синхронизации информации:
GotResponseHeaders: 07:50:52.800
ServerDoneResponse: 07:51:08.471
Полная Timing Info:
== TIMING INFO ============
ClientConnected: 07:50:52.238
ClientBeginRequest: 07:50:52.238
GotRequestHeaders: 07:50:52.238
ClientDoneRequest: 07:50:52.238
Determine Gateway: 0ms
DNS Lookup: 0ms
TCP/IP Connect: 15ms
HTTPS Handshake: 0ms
ServerConnected: 07:50:52.253
FiddlerBeginRequest:07:50:52.253
ServerGotRequest: 07:50:52.253
ServerBeginResponse:07:50:52.800
GotResponseHeaders: 07:50:52.800
ServerDoneResponse: 07:51:08.471
ClientBeginResponse:07:51:08.471
ClientDoneResponse: 07:51:08.471
Overall Elapsed: 0:00:16.233
Кто-нибудь знает, что происходит под капотом, который мог бы объяснить разницу в поведении?
привет, я столкнулся с такой же проблемой здесь. вы нашли решение тем временем? – DanielG
@ DanielG: Боюсь, что нет, но я разместил здесь отчет об ошибке: https://connect.microsoft.com/VisualStudio/feedback/details/1932717/asp-net-bug-issue. Было бы хорошо, если бы вы проголосовали за него, а также нажали ссылку «Я тоже могу» (рядом с «Репро»). – TommyN
Хорошо, сделаю это. Один вопрос: почему бы вам не использовать только ByteArrayContent, если у вас уже есть данные уже в памяти? – DanielG