简体   繁体   English

ASP.NET Web API 2 - StreamContent非常慢

[英]ASP.NET Web API 2 - StreamContent is extremely slow

We've ported a project from WCF to Web API (SelfHost) and during the process we noticed a huge slowdown when serving out a web application. 我们已经将一个项目从WCF移植到Web API(SelfHost),在此过程中我们注意到在提供Web应用程序时出现了巨大的减速。 Now 40-50 seconds vs 3 seconds previously. 现在40-50秒vs 3秒之前。

I've reproduce the issue in a simple console application by adding the various Nuget pacakges for AspNet.WebApi and OwinSelfHost with the following controller: 我通过使用以下控制器为AspNet.WebApi和OwinSelfHost添加各种Nuget pacakges,在一个简单的控制台应用程序中重现了这个问题:

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;

As you can see from the code the only difference is the usage of StreamContent (slooooow) vs ByteArrayContent. 从代码中可以看出,唯一的区别是StreamContent(slooooow)与ByteArrayContent的使用。

The application is hosted on a Win10 machine and accessed from my laptop. 该应用程序托管在Win10机器上,可从我的笔记本电脑访问。 Fiddler shows that it takes 14 seconds to get a single 1MB file from the server to my laptop using StreamContent while ByteArrayContent is less than 1s. Fiddler表示使用StreamContent从服务器到笔记本电脑的单个1MB文件需要14秒,而ByteArrayContent小于1秒。

Also note that the complete file is read into memory to show that the only difference is the Content class used. 另请注意,将完整文件读入内存以显示唯一的区别是使用的Content类。

The strange thing is that it seems that its the transfer itself that is slow. 奇怪的是,它的转移本身似乎很慢。 The server responds with the headers quickly/immediately, but the data takes a long time to arrive as shown by the Fiddler timing info: 服务器快速/立即响应标头,但数据需要很长时间才能到达,如Fiddler定时信息所示:

GotResponseHeaders: 07:50:52.800
ServerDoneResponse: 07:51:08.471

Complete 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

Does anyone know what's going on under the hood that could explain the difference in behavior? 有谁知道引擎盖下发生了什么,可以解释行为上的差异?

The solution to my problem for OWIN self hosting was the StreamContent buffer size. 我的OWIN自托管问题的解决方案是StreamContent缓冲区大小。 The default constructor of StreamContent uses a default value of 0x1000, 4Kb. StreamContent的默认构造函数使用默认值0x1000,4Kb。 On a gigabit network, transfer of 26Mb file takes ~7 minutes to complete at rate of ~60Kb/s. 在千兆网络上,传输26Mb文件需要约7分钟才能以~60Kb / s的速率完成。

 const int BufferSize = 1024 * 1024;
 responseMessage = new HttpResponseMessage();
 responseMessage.Content = new StreamContent(fileStream, BufferSize);

Modifying the bufferSize to 1Mb now take only seconds to complete the download. 现在将bufferSize修改为1Mb只需几秒钟即可完成下载。

[EDIT] In StreamContent SerializeToStreamAsync does a StreamToStreamCopy, according to this link the performance will differ. [编辑]在StreamContent中,SerializeToStreamAsync执行StreamToStreamCopy,根据此链接 ,性能会有所不同。 A suitable value is probably 80K. 合适的值可能是80K。

I'm facing the same issue here, and I think it is related to the Owin self hosting. 我在这里遇到同样的问题,我认为这与Owin自托管相关。 I just created an Asp.net sample Application and hosted it on IIS. 我刚刚创建了一个Asp.net示例应用程序并将其托管在IIS上。 In that case it worked as expected. 在那种情况下,它按预期工作。

The results on my Testsystem while downloading an 80 MB file: 下载80 MB文件时,我的Testsystem上的结果:

  • with Streamcontent and SelfHosting: ~20 minutes 与Streamcontent和SelfHosting:约20分钟
  • with ByteArrayContent and Selfhosting: < 30 seconds 使用ByteArrayContent和Selfhosting:<30秒
  • with Streamcontent and IIS Hosting: < 30 seconds 使用Streamcontent和IIS主机:<30秒

Either there is a configuration setting in ASP.net which I'm missing in my self-hosted project, or there is a bug in owin self-hosting code I guess. ASP.net中有一个我在自托管项目中缺少的配置设置,或者我认为owin自托管代码存在错误。

When you compile the projects, try changing from debug to release. 编译项目时,请尝试从debug更改为release。 It's a loong shot, but would surely increase performance a bit. 这是一个很好的镜头,但肯定会提高性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ASP.NET Web API StreamContent - 使浏览器显示下载进度 - ASP.NET Web API StreamContent - make browser show download progress ASP.Net Web API不读取StreamContent中的所有字节 - ASP.Net Web API doesn't read all bytes from StreamContent 带有数千个临时ASP.NET文件的ASP.NET网站调试极其缓慢 - ASP.NET Web Site Debugging Extremely Slow with several thousand Temporary ASP.NET Files ASP.NET和AJAX库-极慢! - ASP.NET and AJAX library - Extremely slow ! ASP.NET 2.0-4.0 Web应用程序初始启动速度极慢。 - ASP.NET 2.0-4.0 Web Applications experiencing extremely slow initial start-up. 在Docker中创建新的ASP.NET Core MVC应用程序时,NuGet软件包的还原非常缓慢 - NuGet package restore extremely slow when creating new ASP.NET Core MVC app in Docker 简单C#/ asp.net Ajax调用中的DNS查找非常慢 - DNS Lookup in simple C#/asp.net ajax call is extremely slow Web表单中的ASP.NET Web Api - ASP.NET Web Api in Web forms ASP.NET Web API 2.2自身主机对请求的缓慢处理 - asp.net web api 2.2 self host slow processing of requests 从ASP.NET MVC 5中的SQL Server检索图像(以字节[]存储)的速度非常慢 - Extremely slow retrieval images (stored in bytes[]) from SQL Server in ASP.NET MVC 5
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM