0

The controller for my API .NET 4.5.2 is running out of memory when many simultaneous get requests are happening. The out of memory comes from a memory stream downloading large images, which is part of the processing that the request needs to do.

Is there any way besides locking the process method that I can reduce the amount of threads that run at the same time? IE only allow 2-3 process methods to be running at the same time.. This would allow for maximum efficiency while also not running out of memory. Locking the process does fix the out of memory but only allows one process at a time which is not using all the available memory and reduces runtime.

I'm not sure how to access or keep track of the threads that are being created whenever a GET request comes into my api. It is deployed to an Azure server, maybe there is a tool for this? Right now the way I'm accommodating for many users at once is by scaling to multiple instances.

[HttpGet]
[Route("example")]
public HttpResponseMessage GetImage([FromUri] ImageParams imageParams){

Image template = Image.FromFile(
System.Web.Hosting.HostingEnvironment.MapPath("~/Content/Images/image.png");

return ProccessImage(imageParams, template);    

}

Out of memory is thrown on the Image.FromFile line, because the API tries to download all the files at once.

3
  • Can you show us the action method you're using? At least the stream the images are using. Commented Jan 16, 2017 at 18:34
  • You could use a lock after a fixed number of processes are running your GET request. Create a global static counter that increments (Interlocked.Increment) on the method entry and decrements on exit. If that counter reaches your threshold, use a lock. You may need Monitor.Enter/Monitor.Exit (using try/finally) instead the the lock. Commented Jan 16, 2017 at 19:42
  • Could this be done with a semaphore? Could you give an example in code please? Commented Jan 16, 2017 at 20:49

1 Answer 1

1

Keep a count of the number of images being processed, and wait until its small enough for your server to cope with processing an additional image.

Interlocked and try/finally ensure that the count is kept consistently when being changed by multiple threads.

private static int _count = 0;

...

// Wait until other images have finished processing
while (_count >= 4)
{
    Thread.Sleep(200);
}

try
{
    Interlocked.Increment(ref _count);

    // Process it now
    Image template = Image.FromFile(MapPath("~/Content/Images/image.png");

    return ProccessImage(imageParams, template);    
}
finally
{
    Interlocked.Decrement(ref _count);
}

The problem with this is that one unfortunate user could wait forever, if the system is really busy. For more serious applications, you may need to implement a queuing system.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.