2012-04-06 7 views
7

Durante l'utilizzo di MVC MiniProfiler si verifica un errore piuttosto pazzesco. A intermittenza, il sito su cui sto lavorando entra in uno stato in cui ogni richiesta risultati in questa eccezione gettati:MVC Mini-Profiler genera LockRecursionException durante la modifica di RouteCollection

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. 
---> System.TypeInitializationException: The type initializer for 'MvcMiniProfiler.MiniProfiler' threw an exception. 
---> System.Threading.LockRecursionException: Write lock may not be acquired with read lock held. 
This pattern is prone to deadlocks. Please ensure that read locks are released before taking a write lock. 
If an upgrade is necessary, use an upgrade lock in place of the read lock. 
at System.Threading.ReaderWriterLockSlim.TryEnterWriteLockCore(Int32 millisecondsTimeout) 
at System.Threading.ReaderWriterLockSlim.TryEnterWriteLock(Int32 millisecondsTimeout) 
at System.Web.Routing.RouteCollection.GetWriteLock() 
at MvcMiniProfiler.UI.MiniProfilerHandler.RegisterRoutes() 
in C:\Users\sam\Desktop\mvc-mini-profiler\MvcMiniProfiler\UI\MiniProfilerHandler.cs:line 81 
at MvcMiniProfiler.MiniProfiler..cctor() 
in C:\Users\sam\Desktop\mvc-mini-profiler\MvcMiniProfiler\MiniProfiler.cs:line 241 
— End of inner exception stack trace — 
at MvcMiniProfiler.MiniProfiler.get_Current() 
at TotallyNotOverDrive.Boom.MvcApplication.Application_EndRequest() 

L'errore persiste fino a quando il pool di app viene riciclato. Sembra che in qualche modo venga tenuto un blocco che impedisce al MiniProfiler di provare a registrare i percorsi. Ciò si verifica per le richieste in cui non sto avviando il MiniProfiler, ma durante il 10 chiamo MiniProfiler.Stop(), che sembra provocare la creazione di un MiniProfiler quando si accede alla proprietà Corrente. Per una soluzione semplice, ho modificato EndRequest per utilizzare la stessa logica per arrestare il profiler come BeginRequest, quindi se la richiesta non utilizza il profiler questo errore dovrebbe essere evitato completamente. Vorrei ancora risolvere il problema prima di inviare questo codice alla produzione.

La tabella del percorso è piuttosto semplice e viene aggiunta solo al metodo Application_Start. Non usiamo nessun altro codice di terze parti che potrebbe modificare la tabella del percorso dopo l'avvio. L'unica cosa sospetta che ho fatto con il routing è aggiungere un percorso personalizzato alla tabella, ma è un percorso piuttosto semplice, ho solo bisogno di un pattern matching più complicato di quello che potrebbe fare una route MVC standard.

Ho controllato il codice relativo al MiniProfiler e non vedo nulla che possa causare il blocco di un blocco, quindi suppongo che sia una combinazione di ASP.NET e MiniProfiler in conflitto quando si accede a RouteTable. Non riesco a riprodurre il problema in modo affidabile, quindi mi chiedo se qualcun altro ha avuto problemi come questo con il routing. Grazie per l'aiuto che puoi offrire.

risposta

1

Penso di vedere cosa sta succedendo, è necessario ottenere i percorsi registrati prima. Le stai registrando durante lo EndRequest, a questo punto potrebbero esserci altre richieste nella pipeline che stanno tenendo bloccati i blocchi di lettura sulla tabella del percorso.

I percorsi sono registrati nel costruttore statico di MiniProfiler. Se si accede a una qualsiasi delle impostazioni in MiniProfiler durante Application_Start, questo darà il via al costruttore statico che registrerà i percorsi.

Ad esempio, provare ad aggiungere qualcosa come questo, subito dopo aver registrato i percorsi.

MiniProfiler.Settings.PopupMaxTracesToShow = 10;

+1

Ho provato ad aggiungere una chiamata a MiniProfiler.Current in Application_Start, e non è riuscita ancora una volta da quel cambiamento. Era difficile da riprodurre, quindi dovrò dargli più tempo per esserne sicuro. La parte confusa per me è che non funzionava dopo che l'app aveva già inviato alcune richieste, quindi i percorsi avrebbero dovuto essere già registrati una volta. Anche se forse l'abbiamo rilevato quando il pool di app si era addormentato, quindi è stato necessario riavviarlo. – nslowes

Problemi correlati