【问题标题】:Semaphore exception - Adding the specified count to the semaphore would cause it to exceed its maximum count信号量异常 - 将指定计数添加到信号量会导致其超过其最大计数
【发布时间】:2015-05-03 11:15:16
【问题描述】:

我已经有这个 SemaphoreFullException 安静了一段时间了。

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

我已经看到有关此主题的所有其他主题,建议将 Pooling = False 设置为。 我不想这样做,我想继续使用池化,因为它可以带来性能优势。

我正在使用 Entity Framework 6 来查询数据库,并且我没有在用户代码中的任何地方“处理”dbcontext。 看起来问题出在 DbConnectionPool 代码中。

错误在任何给定时刻随机发生。应用程序是否正在使用并不重要。有时,由于这个问题 - 我必须重新启动 IIS,因为新用户停止通过身份验证。

到目前为止我已经尝试过:

  • 检查是否正在释放 DB 事务对象。
  • 检查 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()

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

【问题讨论】:

  • 我们也看到了这种情况 - 您找到解决方案了吗?除了一个含糊的(而且不是 100% 有效)建议关闭连接池之外,Google 搜索没有任何进展,这对我们来说无法扩展。
  • 我没有解决方案,只是一些观察。 DBContext 不打算像这样使用。 DBContext 不是线程安全的。如何管理 DBContent 的线程方面?注意 IIS 调用可能涉及不同的线程。我怎么强调都不过分,考虑转移到短暂的环境中。每个线程至少 1 个。
  • 抱歉回复晚了。我们不得不转向 ADO/批量插入/更新选项以加快查询速度并消除此错误。

标签: c# asp.net-mvc entity-framework linq-to-entities iis-7.5


【解决方案1】:

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

所以我通过命令提示符或 PowerShell 重置了我的 IIS 服务器:iisreset,它成功了。

编辑:查看 IIS Express 的 @aaroncatlin 注释

【讨论】:

  • 我有同样的原因,但iisreset 没有为我解决。相反,我必须在系统托盘中找到 IIS Express,右键单击并退出。当我开始另一个调试会话之后,问题就消失了。
  • 我在调试时停止应用程序后遇到了这个问题。当时只有一个同步数据库查询发生。
【解决方案2】:

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

请记住,数据库连接最终会出现在非托管数据库处理代码中,因此问题是除非垃圾收集处理它在主内存中保持休眠的上下文,从而也阻塞来自连接池的连接。因此,迟早,在适当的条件下,您清空连接池并获得异常。

【讨论】:

【解决方案3】:

我遇到了同样的问题,因为我在关闭连接之前正在做.Dispose();,这就是我解决它的方法:

我有两个.Dispose(); 实例 - 一个在 SqlDataAdapter 中,另一个在一个 SqlCommand 中,然后关闭连接并收到错误。 刚刚从我的 SqlCommand 和我的 SqlDataAdapter 中删除了.Dispose();,不再出现错误!我希望这会有所帮助。

【讨论】:

  • 很高兴您能够解决它。感谢您的反馈。下次遇到这个问题会试试看。
【解决方案4】:

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

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

【讨论】:

    猜你喜欢
    • 2023-01-18
    • 2017-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2017-10-03
    • 2011-07-29
    • 1970-01-01
    相关资源
    最近更新 更多