Исключение семафора. Добавление указанного счетчика в семафор приведет к превышению максимального количества
У меня было это SemaphoreFullException в течение некоторого времени.
Подводя итог.
Я разместил приложение на IIS 7.5 с помощью ASP.NET v4.0 framework Application Pool (интегрированный).
Я использую проверку подлинности Windows для аутентификации моих пользователей через домен (isinrole).
Я видел все другие темы в этой теме, где предлагается установить Pooling = False.
Я не хочу этого делать, и я хотел бы продолжать использовать пул из-за преимуществ производительности.
Я использую Entity Framework 6 для запроса базы данных, и я не "распоряжаю" dbcontext в любом месте кода пользователя.
Похоже, проблема заключается в коде DbConnectionPool.
Ошибка происходит случайным образом в любой момент времени. Не имеет значения, используется ли приложение или нет. Иногда из-за этой проблемы я должен перезапустить IIS, потому что новые пользователи перестают проходить аутентификацию.
Что я пробовал до сих пор:
- Проверьте, удаляется ли объект транзакции DB.
- Проверьте, не установлен ли DBContext (ctx) преждевременно.
- Проверьте сборку приложения (32/62 бит). В этом случае я создаю приложение в ЛЮБОМ режиме процессора, а мой сервер - 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()
Любая помощь в этом отношении будет принята с благодарностью.
Ответы
Ответ 1
Я думаю, что это может быть решением проблемы: http://www.davepaquette.com/archive/2013/03/27/managing-entity-framework-dbcontext-lifetime-in-asp-net-mvc.aspx - Как вы можете видеть, очень важно позаботиться об утилизации DbContext, когда его срок службы истек.
Помните, что соединения Db оказываются в неуправляемом коде обработки db, поэтому проблема заключается в том, что сборщик мусора не удаляет контекст, в котором он спит, в основной памяти, что также блокирует соединение из пула соединений. Поэтому рано или поздно при правильных условиях вы очищаете пул соединений и получаете исключение.
Ответ 2
В моем случае проблема заключалась в том, что я остановил приложение во время отладки. Приложение делало много асинхронных вызовов.
Поэтому я сбросил свой сервер IIS: iisreset
через командную строку или PowerShell, и это сработало.
РЕДАКТИРОВАТЬ: Посмотрите на комментарий @aaroncatlin для IIS Express
Ответ 3
У меня была такая же проблема, и потому, что я делал .Dispose();
, прежде чем закрывать соединение, я решил:
У меня было два экземпляра .Dispose();
- один в SqlDataAdapter, другой в одном SqlCommand и после этого закрывал соединение и получал ошибку.
Просто удалил .Dispose();
из моего SqlCommand и моего SqlDataAdapter, и больше не было ошибок! Надеюсь, это поможет как-то.