Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET Web API StreamContent vs IIS Static File handler

I'm putting together a document-management service using ASP.NET Web API, and performance is of some concern.

Based on this article by Nathanael Jones, author of the IIS / ASP.NET ImageResizer module, I've developed a few preconceptions on what's necessary for "optimal" performance of serving static files. The precis of that being:

  1. Use a HttpModule because it's very early in the ASP.NET pipeline (less pipeline = more optimised) and turns out to be easier to deal with this sort of thing than a HttpHandler.
  2. Response.WriteFile(filename) is better than Response.Write(memBuffer) where memBuffer is an in-memory C# buffer.
  3. A URL rewrite (i.e. Context.RewritePath(virtualPath)) is better than Response.WriteFile(filename), because it will use the IIS static file handler, which is well optimised.

Trouble is, thanks to some bizarre caching issue I still can't get to the bottom of (here), my URL rewrite technique isn't behaving itself.

So now I'm left wondering about a more Web API-centric implementation like the following:

public Task<HttpResponseMessage> DoTheFoo()
{
    return Task<HttpResponseMessage>.Factory.StartNew(() =>
    {
        var response = new HttpResponseMessage();
        response.Headers.Add("Content-Disposition", "inline; filename=\"" + attachmentFileName + "\"");
        response.Headers.Add("content-type", mimeType);
        response.Content = new StreamContent(File.OpenRead("somefile.doc"));

        return response;
    });
}

For a Web API solution this obviously makes things a bit neater, since the file-serving portions of the service can go right alongside the other actions in controllers, but how well is it going to perform and scale? The factors I ponder:

  1. Network bandwidth. Presumably no difference here, all techniques are writing the same number of bytes.
  2. Speed of writing to the outgoing network stream. IIS static file handler might be a bit better at this than the ASP.NET pipeline? Maybe less of an issue with integrated pipeline? The service will be serving on anything between a consumer-level couple-of-hundred kbits DSL line, up to a gbit LAN.
  3. RAM usage. I'm assuming the StreamContent implementation won't be as efficient as IIS static file handler.
  4. CPU usage. As with RAM, I'm assuming StreamContent is going to be a little more demanding than the IIS static file handler.
  5. Server-side caching. IIS static file handler offers this (and is precisely what's giving me hassle because it doesn't seem to be behaving itself), but presuming I could get it to behave itself, that's going to offer benefits ahead of the StreamContent implementation. I'm not so worried about this aspect though as the service is more likely to be responding to a lot of different file requests, as opposed to the same ones repeatedly.

I'm not in a position to put together a server-farm to test this to get real performance numbers, and I have my doubts that factoring up small-scale test results will give anything accurate. So from those in the know, what sort of differences could I expect? I'm almost ready to abandon the URL rewrite implementation, but if it's going to give me a noticeable performance hit, I'll persevere.

like image 503
Snixtor Avatar asked Nov 12 '22 11:11

Snixtor


1 Answers

Not sure if you are planning to host in Azure, but if you are you can use a dedicated public blob storage container for your images. Then use the CDN service to serve (and cache) the static files for you. This will move the problem off your API and into a CDN, which is designed to handle static resources.

like image 59
Paul Fryer Avatar answered Dec 23 '22 20:12

Paul Fryer