信号量异常 - 将指定的计数添加到信号量将导致它超过其最大计数

Ali*_*der 16 c# asp.net-mvc linq-to-entities entity-framework iis-7.5

我一直在安静这个SemaphoreFullException.

总结一下..我在IIS 7.5上托管了一个带有ASP.NET v4.0框架应用程序池(集成)的应用程序.我正在使用Windows身份验证通过域(isinrole)验证我的用户.

我已经看过这个主题的所有其他主题,建议设置Pooling = False.我不想那样做,因为性能优势,我想继续使用池.

我正在使用Entity Framework 6来查询数据库,我没有在用户代码中的任何地方"处理"dbcontext.看起来这个问题出现在DbConnectionPool代码中.

错误在任何给定时刻随机发生.无论是否使用该应用程序都无关紧要.有时,由于此问题 - 我必须重新启动IIS,因为新用户停止进行身份验证.

到目前为止我尝试过的:

  • 检查是否正在处理数据库事务对象.
  • 检查DBContext(ctx)是否过早处理.
  • 检查应用程序构建(32/62位).在这种情况下 - 我在任何CPU模式下构建应用程序,我的服务器是64位.

注意:在我的应用程序中,我主要使用linq-to-EF对象来查询数据库.

Exception: System.Threading.SemaphoreFullException

Message: Adding the specified count to the semaphore would cause it to exceed its maximum count.

StackTrace:    at System.Threading.Semaphore.Release(Int32 releaseCount)
   at System.Data.ProviderBase.DbConnectionPool.CleanupCallback(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.TimerQueueTimer.CallCallback()
   at System.Threading.TimerQueueTimer.Fire()
   at System.Threading.TimerQueue.FireNextTimers()
Run Code Online (Sandbox Code Playgroud)

在这方面的任何帮助将不胜感激.

Lui*_*jon 12

就我而言,问题是我在调试时停止了应用程序.该应用程序正在进行大量的异步调用.

所以我重置我的IIS服务器:iisreset通过命令提示符或PowerShell,它工作.

  • 我有同样的原因,但 `iisreset` 没有为我解决它。相反,我必须在系统托盘中找到 IIS Express,右键单击并退出。当我开始另一个调试会话时,问题就消失了。 (2认同)

小智 10

我最近遇到了 SemaphoreSlim 的类似问题。有问题的代码如下,并且在 中引发了相同的异常semaphoreSlime.Release()。这里的原因是WaitAsync由于令牌取消而失败,因此Release()将导致超出允许的最大计数。因此,解决方案可以是在调用之前添加一些防御代码Release(),例如检查是否发生异常WaitAsync,检查允许的帐户是否超出允许的数量。

try
{
   await semaphoreSlim.WaitAsync(cancellationToken);
   // do some work
}
catch (OperationCanceledException)
{
   // exception handling
}
finally
{
   semaphoreSlim.Release();
}
Run Code Online (Sandbox Code Playgroud)

  • 另一个解决方案是将“await semaphoreSlim.WaitAsync(cancellationToken);”行移至 try 块**上方**。在这种情况下,取消的令牌将不会触发finally块。 (2认同)

flo*_*ack 5

我认为,这可能是解决问题的办法:http://www.davepaquette.com/archive/2013/03/27/managing-entity-framework-dbcontext-lifetime-in-asp-net-mvc.aspx -如您所见,当DbContext的生命周期结束时,务必要小心处理。

请记住,Db连接最终会以非托管的db处理代码结束,因此问题在于,除非垃圾回收将上下文保留在主内存中,否则垃圾也会阻塞来自连接池的连接。因此,在适当的条件下,迟早要清空连接池并获取异常。

  • 我目前正在寻找此问题的解决方案。[这是EF开发团队的高级负责人Diego Vega必须说的是,不丢弃上下文无害。](http://blog.jongallant.com/2012/10/do-i-have-to -call-dispose-on-dbcontext.html) (2认同)