2017-01-16 62 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); 
} 

問題是,如果系統真的很忙,一個不幸的用戶可能會永遠等待。對於更嚴重的應用程序,您可能需要實施排隊系統。