2012-04-06 3 views
7

Ich sehe einen ziemlich verrückten Fehler bei der Verwendung der MVC. Intermittently tritt die Seite, die ich bin auf einen Zustand, in dem alle geworfen Anfrage Ergebnisse in dieser Ausnahme werden:MVC Mini-Profiler löst LockRecursionException beim Ändern von 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() 

Der Fehler bleibt bestehen, bis die app-Pool zurückgeführt wird. Es sieht so aus, als ob eine Sperre gehalten wird, die verhindert, dass der MiniProfiler versucht, seine Routen zu registrieren. Dies tritt bei Anfragen auf, bei denen ich den MiniProfiler nicht starte, aber während Application_EndRequest rufe ich MiniProfiler.Stop() an, was dazu führt, dass ein MiniProfiler erstellt wird, wenn auf die Eigenschaft Current zugegriffen wird. Für eine einfache Lösung habe ich EndRequest so geändert, dass dieselbe Logik verwendet wird, um den Profiler als BeginRequest zu stoppen. Wenn also die Anforderung den Profiler nicht verwendet, sollte dieser Fehler vollständig vermieden werden. Ich möchte immer noch das eigentliche Problem lösen, bevor ich diesen Code an die Produktion sende.

Meine Routentabelle ist ziemlich einfach und wird nur innerhalb der Application_Start Methode hinzugefügt. Wir verwenden keinen anderen Code von Drittanbietern, der die Routentabelle nach dem Start möglicherweise ändert. Die einzige verdächtige Sache, die ich mit dem Routing gemacht habe, ist das Hinzufügen einer benutzerdefinierten Route zur Tabelle, aber es ist eine ziemlich einfache Route, ich brauchte nur etwas komplizierteres Pattern-Matching, als eine Standard-MVC-Route erreichen könnte.

Ich habe den relevanten MiniProfiler-Code durchgesehen und sehe nichts, was dazu führen könnte, dass eine Sperre unveröffentlicht wird. Daher gehe ich davon aus, dass es eine Kombination aus ASP.NET und MiniProfiler beim Zugriff auf RouteTable ist. Ich kann das Problem nicht zuverlässig reproduzieren, also frage ich mich, ob jemand anderes Probleme mit dem Routing hatte. Vielen Dank für Ihre Hilfe.

Antwort

1

Ich denke, ich sehe, was passiert, müssen Sie die Routen früher registriert bekommen. Sie registrieren sie während EndRequest, zu diesem Zeitpunkt gibt es möglicherweise andere Anforderungen in der Pipeline, die Lese-Sperren für die Routentabelle enthalten.

Die Routen sind im statischen Konstruktor von MiniProfiler registriert. Wenn Sie unter Application_Start auf eine der Einstellungen in MiniProfiler zugreifen, startet dies den statischen Konstruktor, der die Routen registriert.

Versuchen Sie zum Beispiel, etwas hinzuzufügen, gleich nachdem Sie Ihre Routen registriert haben.

MiniProfiler.Settings.PopupMaxTracesToShow = 10;

+1

Ich habe versucht, einen Anruf zu MiniProfiler.Current in Application_Start zugibt und es seit dieser Änderung nicht wieder gescheitert ist. Es war schwierig zu reproduzieren, also muss ich ihm mehr Zeit geben, um sicher zu gehen. Der verwirrende Teil für mich ist, dass es fehlgeschlagen ist, nachdem die App bereits einige Anfragen erfüllt hat, also sollten die Routen bereits einmal registriert worden sein. Obwohl wir es vielleicht erwischt haben, als der App-Pool eingeschlafen war, musste er wieder starten. – nslowes

Verwandte Themen