2

There is a controller in or Web API that returns files to users so that they download them. We use StreamContent to serve files in the following way:

...

var fileStream = System.IO.File.Open(@"C:\files\1GB.bin", FileMode.Open, 
  FileAccess.Read);
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Headers.AcceptRanges.Add("bytes");
var content = new StreamContent(fileStream, BufferSize);
response.Content = content;

...

return response;

There was an issue with files being downloaded very slow (~15 MB/s on the local machine when downloading a 1 GB example file). According to ASP.NET Web API 2 - StreamContent is extremely slow, the buffer size can affect the download speed, so I have changed the code by increasing BufferSize, trying 1 MB or 80 KBs. The results got much better (like ~100 MB/s for the file), but for some reason, if I perform several consequential downloads (download file once, then second time, then 3rd, etc, every time start the new download only after the first one has been completed), then after the second or third try the speed falls to ~15 MB/s again. There is no difference in memory used by IIS Worker Process, the difference, however, appears in CPU usage and I do not understand why this happens.

When a file is downloading quickly, the CPU load varies from 5 to 25% at max, but when download works slowly, the load is about ~35%.

Also tried using PushStreamContent and got the same results: several downloads are fast, then speed falls. Then, after project rebuild or after some time passes, the speed is high again.

What can be the reason for such behavior? Or, maybe there is a better way of serving files in ASP.NET Web API?

EDIT: for some reason, I can reproduce this behavior only locally, on other machines the problem is not reproduced. Do not know what can be the reason for it though.

MyUserName
  • 495
  • 2
  • 6
  • 24
  • Have you checked he I/O cost during the transfer. Are you using single .Net application to test sequential downloads? if so you can check on ServicePoint Manager, Default Connection Limit Limitation. have you thought of using CDN service to serve the files? – Roy Aug 07 '19 at 10:21
  • This is a single application which I'm currently testing locally. And yes, I do sequential downloads. Only after the file is downloaded, I am starting another download. It is really interesting as first 1-2, sometimes 3 downloads are very fast, and then performance drops. I am not sure if number of concurrent connections affects the download as I am not doing any requests to the app besides downloading file. And CDN is not an option in this case unfortunately:(. – MyUserName Aug 07 '19 at 10:54
  • I've ran into this issue before, have a look at my answer at - https://stackoverflow.com/a/43891035/5474410 I'm pretty sure it will solve the issue with large files. – Janus Pienaar Aug 08 '19 at 07:16
  • @JanusPienaar thank you! Is it possible to use Response in ASP.NET Web API instead of HttpResponseMessage? – MyUserName Aug 08 '19 at 09:14

0 Answers0