Przenieśliśmy projekt z WCF do Web API (SelfHost) i podczas procesu zauważyliśmy ogromne spowolnienie podczas udostępniania aplikacji internetowej. Teraz 40-50 sekund vs 3 sekundy wcześniej.ASP.NET Web API 2 - StreamContent jest bardzo powolny
mam odtworzyć problem w prostej aplikacji konsoli dodając różne Nuget Pacakges dla AspNet.WebApi i OwinSelfHost z poniższego regulatora:
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;
Jak widać z kodu Jedyną różnicą jest korzystanie z StreamContent (slooooow) vs ByteArrayContent.
Aplikacja jest hostowana na maszynie Win10 i jest dostępna z mojego laptopa. Fiddler pokazuje, że uzyskanie pojedynczego pliku o wielkości 1 MB z serwera na mój laptop zajmuje 14 sekund przy użyciu StreamContent, podczas gdy wartość ByteArrayContent jest mniejsza niż 1s.
Należy również pamiętać, że cały plik jest wczytany do pamięci, aby pokazać, że jedyną różnicą jest używana klasa zawartości.
Dziwne jest to, że wydaje się, że jego transfer jest powolny. Serwer odpowiada z nagłówkami szybko/od razu, ale dane zajmuje dużo czasu, aby dotrzeć jak pokazuje Fiddler synchronizacji informacji:
GotResponseHeaders: 07:50:52.800
ServerDoneResponse: 07:51:08.471
Kompletna 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
Czy ktoś wie co się dzieje pod maską, która może wyjaśnić różnicę w zachowaniu?
Cześć, mam tu dokładnie ten sam problem. czy znalazłeś rozwiązanie w międzyczasie? – DanielG
@DanielG: Obawiam się, że nie, ale wysłałem tutaj raport o błędzie: https://connect.microsoft.com/VisualStudio/feedback/details/1932717/asp-net-bug-issue. Byłoby dobrze, gdybyście głosowali nad nim, a także kliknęli link "Mogę też" (obok Repros). – TommyN
OK, zrobi to. Jedno pytanie: dlaczego nie używasz tylko ByteArrayContent, jeśli masz dane już w pamięci? – DanielG