0

I have this site that streams images from the database (SQL2008), and I think it's the one causing the very high CPU usage on my server. The CPU usage is at least 60-90%.

I am using MVC3 and below is the code in my Controller that sends the image to the View:

 [OutputCache(Duration = 86400, VaryByParam = "GUID")]
 public FileStreamResult GetFile(string guid)
    {
        Guid id = new Guid(guid);
        Thumbnail thumbnail = thumbService.GetThumbnailByGUID(id);
        Stream stream = new MemoryStream(thumbnail.FileContent.ToArray());
        var fsr = new FileStreamResult(stream, "image");
        return fsr;
    }

The View:

 <div style="background:url('@url');background-repeat:no-repeat;background-position:50% top;background-color:#fff;" class="photoThumb">

The @url above is /GetFile/guid

Can anyone tell me what I'm doing wrong?

Thanks

Updates on the answer and another question:

The [OutputCache(Duration = 86400, VaryByParam = "GUID")] from the answer below worked and has improved the performance of the site. The CPU usage has now went down to 8-60% but I also want to make sure that everything is disposed so I want to know if FileStreamResult is doing that for me or should I do it manually?

dmc
  • 807
  • 2
  • 10
  • 25
  • Is it possible to store only image path in database instead of whole image? – alok_dida May 29 '12 at 04:51
  • @alok_dida Yes it's possible, but that would mean a complete re-do on my end. And I want the images in the database for migration purposes. – dmc May 29 '12 at 05:48
  • Ok. I would like to add one more thing, please dispose all the objects else there will be an issue of memory lick. You can use using(resource) clause for it. – alok_dida May 29 '12 at 06:14
  • @alok_dida, Isn't that already handled by FileStreamResult? I did some research on that one and they are saying that FileStreamResult handles the Dispose. Not sure though. Anyways, I tried Using(Stream stream = new MemoryStream(thumbnail.FileContent.ToArray())){return new FileStreamResult(stream, "image");} but the images doesn't show. Am I doing it wrong? The OutputCache suggested by Stank below works for me but I also want to make sure everything is disposed. – dmc May 29 '12 at 09:39
  • Can you please provide the code for View and function? – alok_dida May 29 '12 at 11:06
  • Hi @alok_dida I have updated the question with the complete code and with the question regarding FileStreamResult. – dmc May 29 '12 at 11:28
  • Look my below code and also refer this url http://stackoverflow.com/questions/3084366/how-do-i-dispose-my-filestream-when-implementing-a-file-download-in-asp-net – alok_dida May 29 '12 at 12:19
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/11876/discussion-between-alok-dida-and-duncan-mcintyre) – alok_dida May 29 '12 at 13:14

2 Answers2

3

I'd guess that there is a database hit for each image request, with multiple images per page request - this could lead to high CPU usage. You should try caching the images.

If you decorate your action with

[OutputCache( Duration = 86400, VaryByParam = "id" )]

this should cache the result image for one day, meaning fewer db queries, and hopefully less load on your server.

StanK
  • 4,750
  • 2
  • 22
  • 46
  • Yes @StanK you are correct, each image request hits the database. Thanks for the advice, I'll try this out and will let you know how it goes. – dmc May 29 '12 at 05:47
  • the OutputCache works for me. Thanks, but I also want to make sure that everything in my code is disposed. Question: Does FileStreamResult do that for me? Or do I have to do it myself? Thanks again! – dmc May 29 '12 at 09:41
0

You can also modify as below.

[OutputCache(Duration = 86400, VaryByParam = "GUID")]
     public FileStreamResult GetFile(string guid)
        {
            Guid id = new Guid(guid);
            Thumbnail thumbnail = thumbService.GetThumbnailByGUID(id);
            var fsr; 
            using(Stream stream = new MemoryStream(thumbnail.FileContent.ToArray()))
            {
                fsr = new FileStreamResult(stream, "image");
            }
            return fsr;
        }

As mentioned in above comment, when your page render FileStreamResult will automatically dispose.

alok_dida
  • 1,723
  • 2
  • 17
  • 36
  • @aloka_dida, the above modifications doesn't work. The images are not rendered in my view. – dmc May 29 '12 at 13:27
  • The reason is that @alok_dida is using the using(stream... statement. This disposes the stream before it can send it. – AboutDev Jan 09 '13 at 04:46