【问题标题】:ASP.NET MVC Controller threads causing OutOfMemoryExceptionASP.NET MVC 控制器线程导致 OutOfMemoryException
【发布时间】:2017-01-16 18:19:15
【问题描述】:

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

除了锁定进程方法之外,还有什么方法可以减少同时运行的线程数量吗? 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);    

}

Image.FromFile 行会抛出内存不足,因为 API 会尝试一次下载所有文件。

【问题讨论】:

  • 您能告诉我们您正在使用的操作方法吗?至少是图像使用的流。
  • 您可以在固定数量的进程运行您的 GET 请求后使用锁。创建一个全局静态计数器,在方法进入时递增(Interlocked.Increment),在退出时递减。如果该计数器达到您的阈值,请使用锁。您可能需要 Monitor.Enter/Monitor.Exit(使用 try/finally)而不是锁。
  • 这可以用信号量来完成吗?可以举个代码例子吗?

标签: c# asp.net asp.net-mvc multithreading


【解决方案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);
}

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

【讨论】:

    猜你喜欢
    • 2015-08-24
    • 2018-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2015-02-06
    • 2018-11-24
    • 1970-01-01
    相关资源
    最近更新 更多