2015-05-03 32 views
13

Ho avuto questo SemaphoreFullException per un po 'di tempo.Eccezione di semaforo - L'aggiunta del conteggio specificato al semaforo causerebbe il superamento del conteggio massimo

Per riepilogare .. Ho ospitato un'applicazione su IIS 7.5 con ASP.NET v4.0 framework Pool di applicazioni (integrato). Sto usando l'autenticazione di Windows per autenticare i miei utenti attraverso il dominio (isinrole).

Ho visto tutti gli altri thread su questo argomento, in cui è consigliabile impostare Pooling = False. Non voglio farlo e mi piacerebbe continuare a utilizzare il pool a causa dei vantaggi in termini di prestazioni.

Sto utilizzando Entity Framework 6 per interrogare il database e non sto "eliminando" il dbcontext da nessuna parte nel codice utente. Sembra che il problema sia nel codice DbConnectionPool.

L'errore si verifica in modo casuale in un determinato momento. Non importa se l'applicazione viene utilizzata o meno. A volte, a causa di questo problema, devo riavviare IIS perché i nuovi utenti smettono di essere autenticati.

Quello che ho provato finora:

  • Controllare se un oggetto di transazione DB è in via di dismissione.
  • Verificare se un DBContext (ctx) viene smaltito prematuramente.
  • Verificare la build dell'applicazione (32/62 bit). In questo caso, creo l'applicazione in QUALSIASI modalità CPU e il mio server è a 64 bit.

Nota: Nella mia applicazione, ho utilizzato principalmente oggetti linq-to-EF per interrogare il DB.

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() 

Qualsiasi aiuto in questo senso sarà molto apprezzato.

+0

Stiamo vedendo anche questo - hai mai trovato una soluzione? La ricerca di Google non portava da nessuna parte in fretta, a parte una raccomandazione vaga (e non al 100% efficace) per disattivare il pool di connessioni, che non sarebbe scalabile per noi. –

+1

Non ho una soluzione, solo alcune osservazioni. Il DBContext non è stato progettato per essere utilizzato come. DBContext non è thread-safe. Come gestisci l'aspetto del thread del tuo DBContent? Nota Le chiamate IIS possono coinvolgere diversi thread. Non posso enfatizzare abbastanza prendere in considerazione il passaggio a contesti di breve durata. a un minimo 1 per filo. –

+0

Scuse per la risposta tardiva. Abbiamo dovuto passare alle opzioni ADO/Bulk insert/update per velocizzare l'interrogazione e annullare questo errore. –

risposta

4

Penso che questa possa essere una soluzione al problema: http://www.davepaquette.com/archive/2013/03/27/managing-entity-framework-dbcontext-lifetime-in-asp-net-mvc.aspx - come puoi vedere, è essenziale occuparsi dello smaltimento di DbContext quando la vita è finita.

Ricordare che le connessioni Db finiscono nel codice di gestione db non gestito, quindi il problema è che a meno che la garbage collection non disponga del contesto in cui rimane nella memoria principale, bloccando anche una connessione dal pool di connessioni. Quindi prima o poi, nelle giuste condizioni, svuoti il ​​pool di connessioni e ottieni la tua eccezione.

+0

Forse questa è la ragione del problema. Tuttavia, ho dovuto passare da EF6 DBContext a ADO ed è stato in grado di risolvere gli errori. Contrassegnare il collegamento per riferimenti futuri. Grazie! –

+2

Attualmente sto cercando una soluzione a questo problema. [Ecco cosa Diego Vega, Senior Lead del team di sviluppo di EF, ha detto che è innocuo non smaltire il contesto.] (Http://blog.jongallant.com/2012/10/do-i-have-to -call-dispose-on-dbcontext.html) – busitech

0

Ho avuto lo stesso problema ed era perché stavo facendo .Dispose(); prima di chiudere il collegamento ecco come ho risolto:

ho avuto due istanze di .Dispose(); - uno in uno SqlDataAdapter, l'altro in un unico SqlCommand e dopo stava chiudendo la connessione e ottenendo l'errore. Ho appena rimosso il .Dispose(); dal mio SqlCommand e dal mio SqlDataAdapter, e non ho più errori! Spero che questo aiuti in qualche modo.

+0

Felice di essere stato in grado di risolverlo. Grazie per il feedback. Ci provo la prossima volta che ho questo problema. –

7

Nel mio caso, il problema era che ho interrotto l'applicazione durante il debug. L'applicazione stava effettuando molte chiamate asincrone.

Così ho resettato il mio server IIS: iisreset tramite prompt dei comandi o PowerShell, e ha funzionato.