Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET Web API 2-StreamContent非常慢_C#_Asp.net_Asp.net Web Api - Fatal编程技术网

C# ASP.NET Web API 2-StreamContent非常慢

C# ASP.NET Web API 2-StreamContent非常慢,c#,asp.net,asp.net-web-api,C#,Asp.net,Asp.net Web Api,我们已经将一个项目从WCF移植到Web API(SelfHost),在这个过程中,我们注意到在提供Web应用程序时速度大大减慢。现在是40-50秒,而之前是3秒 我在一个简单的控制台应用程序中重现了这个问题,为AspNet.WebApi和OwinSelfHost添加了各种Nuget包,其中包含以下控制器: var stream = new MemoryStream(); using (var file = File.OpenRead(filename)) { file.CopyTo(st

我们已经将一个项目从WCF移植到Web API(SelfHost),在这个过程中,我们注意到在提供Web应用程序时速度大大减慢。现在是40-50秒,而之前是3秒

我在一个简单的控制台应用程序中重现了这个问题,为AspNet.WebApi和OwinSelfHost添加了各种Nuget包,其中包含以下控制器:

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(slooow)与ByteArrayContent的用法

该应用程序托管在Win10机器上,并可从我的笔记本电脑访问。 Fiddler显示,使用StreamContent将一个1MB的文件从服务器发送到我的笔记本电脑需要14秒,而ByteArrayContent则不到1秒

还要注意,完整的文件被读入内存,以表明唯一的区别是所使用的内容类

奇怪的是,传输本身似乎很慢。服务器会快速/立即响应标题,但数据需要很长时间才能到达,如Fiddler计时信息所示:

GotResponseHeaders: 07:50:52.800
ServerDoneResponse: 07:51:08.471
完整的时间信息:

== 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

有人知道幕后发生了什么可以解释行为上的差异吗?

编译项目时,请尝试从调试更改为发布。这是一个长镜头,但肯定会提高性能一点。

我在这里面临同样的问题,我认为这与Owin自托管有关。我刚刚创建了一个Asp.net示例应用程序,并将其托管在IIS上。在那种情况下,它按预期工作

下载80 MB文件时在我的测试系统上的结果:

  • 使用Streamcontent和自托管:~20分钟
  • 使用ByteArrayContent和自托管:<30秒
  • 使用Streamcontent和IIS托管:<30秒

要么是ASP.net中有一个配置设置,而我的自托管项目中缺少该设置,要么是owin自托管代码中有一个bug。

解决owin自托管问题的方法是StreamContent缓冲区大小。StreamContent的默认构造函数使用默认值0x1000,4Kb。在千兆网络上,以约60Kb/s的速率传输26Mb文件需要约7分钟才能完成

 const int BufferSize = 1024 * 1024;
 responseMessage = new HttpResponseMessage();
 responseMessage.Content = new StreamContent(fileStream, BufferSize);
现在将bufferSize修改为1Mb只需几秒钟即可完成下载


[EDIT]在StreamContent SerializeToStreamAsync中,根据性能的不同,执行StreamToStreamCopy。一个合适的值可能是80K。

恐怕没有什么区别。嗨,我在这里面临着完全相同的问题。你同时找到解决方案了吗?@DanielG:恐怕没有,但我在这里发布了一个bug报告:。如果你投票并点击“我也可以”链接(在“复制”旁边),那就太好了。好的,我会这么做的。一个问题:如果内存中已经有数据,为什么不直接使用ByteArrayContent?请尝试调整StreamContent缓冲区大小()。默认值只有4kb,这将导致许多写入操作。@hiFI我使用Fiddler。。。但是数据需要很长时间才能到达,如Fiddler计时信息所示