2017-01-16 63 views
0

当许多同时发生的请求发生时,我的API .NET 4.5.2的控制器内存不足。内存不足来自内存流下载大图像,这是请求需要执行的处理的一部分。导致OutOfMemoryException的ASP.NET MVC控制器线程

除了锁定可以减少同时运行的线程数量的进程方法外,还有其他办法吗? IE只允许同时运行2-3个过程方法。这样可以实现最高效率,同时也不会耗尽内存。锁定进程确实解决了内存不足的问题,但是一次只允许一个进程不使用所有可用内存并减少运行时间。

我不知道如何访问或跟踪每当GET请求进入我的api时正在创建的线程。它被部署到Azure服务器,也许有一个工具呢?现在我一次适应许多用户的方式是扩展到多个实例。

[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);  

} 

由于API试图一次下载所有文件,Image.FromFile行会抛出内存不足。

+0

你能告诉我们你正在使用的操作方法吗?至少是图像使用的流。 – krillgar

+0

在编辑中完成 – Jaked222

+0

在固定数量的进程正在运行GET请求后,您可以使用锁定。创建一个全局静态计数器,用于在方法条目上递增(Interlocked.Increment),并在退出时递减。如果该计数器达到您的阈值,请使用锁定。您可能需要Monitor.Enter/Monitor.Exit(使用try/finally)代替锁。 –

回答

1

保持正在处理的图像数量的计数,并等到其足够小以使服务器能够处理额外的图像。

Interlocked并尝试/最终确保计数在被多个线程更改时保持一致。

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); 
} 

问题是,如果系统真的很忙,一个不幸的用户可能会永远等待。对于更严重的应用程序,您可能需要实施排队系统。