2012-04-06 22 views
7

Tôi thấy một lỗi khá điên lên khi sử dụng MVC MiniProfiler. Không liên tục, trang web tôi đang làm việc để vào trạng thái mà mọi yêu cầu dẫn đến ngoại lệ này bị ném ra:MVC Mini-Profiler ném LockRecursionException khi sửa đổi 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ỗi vẫn tồn tại cho đến khi hồ bơi ứng dụng được tái chế. Có vẻ như một khóa nào đó đang được giữ để ngăn MiniProfiler cố gắng đăng ký các tuyến đường của nó. Điều này xảy ra cho các yêu cầu mà tôi không khởi động MiniProfiler, nhưng trong thời gian Application_EndRequest tôi gọi MiniProfiler.Stop(), điều này có vẻ dẫn đến một MiniProfiler được tạo khi thuộc tính hiện tại được truy cập. Đối với một giải pháp đơn giản, tôi đã sửa đổi EndRequest để sử dụng cùng một logic để dừng profiler như BeginRequest, vì vậy nếu yêu cầu không sử dụng profiler thì lỗi này nên tránh hoàn toàn. Tôi vẫn muốn giải quyết vấn đề thực tế trước khi gửi mã này đến sản xuất.

Bảng tuyến đường của tôi khá đơn giản và chỉ được thêm vào trong phương thức Application_Start. Chúng tôi không sử dụng bất kỳ mã của bên thứ ba nào khác có thể đang sửa đổi bảng định tuyến sau khi khởi động. Điều nghi ngờ duy nhất tôi đã thực hiện với định tuyến là thêm một Route tùy chỉnh vào bảng, nhưng đó là một tuyến đường khá đơn giản, tôi chỉ cần một số mô hình phức tạp hơn so với một tuyến đường MVC tiêu chuẩn có thể thực hiện.

Tôi đã xem qua mã MiniProfiler có liên quan và không thấy bất kỳ thứ gì có thể khiến khóa không được phát hành, vì vậy tôi cho rằng đó là sự kết hợp giữa ASP.NET và MiniProfiler xung đột khi truy cập vào RouteTable. Tôi không thể tái tạo một cách đáng tin cậy vấn đề, vì vậy tôi tự hỏi nếu có ai khác đã có vấn đề như thế này với định tuyến. Cảm ơn vì những giúp đỡ của bạn.

Trả lời

1

Tôi nghĩ rằng tôi thấy điều gì đang xảy ra, bạn cần phải nhận các tuyến đường đã đăng ký trước đó. Bạn đang đăng ký chúng trong EndRequest, tại thời điểm này có thể có các yêu cầu khác trong đường ống đang nắm giữ các khóa đọc trên bảng định tuyến.

Các tuyến đường được đăng ký trong hàm dựng tĩnh của MiniProfiler. Nếu bạn truy cập bất kỳ cài đặt nào trong MiniProfiler trong thời gian Application_Start, điều này sẽ khởi chạy hàm tạo tĩnh sẽ đăng ký các tuyến.

Ví dụ: hãy thử thêm một cái gì đó như thế này, ngay sau khi đăng ký tuyến đường của bạn.

MiniProfiler.Settings.PopupMaxTracesToShow = 10;

+1

Tôi đã thử thêm một cuộc gọi đến MiniProfiler.Current trong Application_Start, và nó đã không thất bại một lần nữa kể từ khi thay đổi đó. Rất khó để tái sản xuất, vì vậy tôi sẽ phải dành thêm thời gian để chắc chắn. Phần khó hiểu với tôi là nó đã thất bại sau khi ứng dụng đã phục vụ một số yêu cầu, vì vậy các tuyến đường nên đã được đăng ký một lần. Mặc dù có lẽ chúng tôi đã bắt được nó khi hồ bơi ứng dụng đã đi ngủ, vì vậy nó phải bắt đầu lại. – nslowes

Các vấn đề liên quan