jloper
jloper

Reputation: 49

Why does IIS Express Restart my App Pool in MVC Application

I have a fairly complex MVC Application which must initialize when the Application starts. I am trying to diagnose why the App pool is restarting after the first MVC page is rendered. To diagnose this issue, I put break points on Application_Start and Application_End. Applicaiton_Start is called as expected. At the end of the first returned HTML/Razor page from my application, Application_End is called. On the next page request, Application_Start get called again, and then seems to run as expected without restarting.

I thought this was caused by Razor compiling the views at runtime, which would then updating the BIN foldee. I know that IIS and IIS Express restart the APP pool when the BIN folder is updated, so I assumed this MVC Razor compllation was causing the IIS process to restart the app pool. To mitigate this, I followed the instructions here: https://chrismckee.co.uk/asp-net-mvc-compiled-views/ to pre-compile my Razor views. I know that the vies are now pre-compiled, as this did locate several compile issues [compile errors] that would not have been found until runtime without these configuration changes resulting in the pre-complication of the Razor views.

So the question is this:

1) How Can I diagnose why the app pool is restarting?

2) Does anyone know why this happens in and MVC application running in IISExpress?

[... and obviously, how to prevent it from happening]

Thanks

jloper

Update #2:

I looked up Browser Link and figured out quickly that it not necessary and really not being used. I turn off BrowserLink and sure enough, the exception goes away. Now the Application_Start is called as expected, Application_End is called [and no exception has occurred (System.GetLastError() returns null]. Application_Exception is NEVER called. Application_Start is called a second time.

All state of the application is reset when the Application_End is called.

Update #1:

As suggested, I added Application_Error and retrieved the last exception using Server.GetLastError(). Here is the exception that was returned:

The thread 0xc4c has exited with code 259 (0x103).
System.Web.HttpException (0x80004005): The controller for path '/__browserLink/requestData/8cf754f80e264fd392f4a0fbffea67e4' was not found or does not implement IController.
   at System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType)
   at System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName)
   at System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory)
   at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state)
   at System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state)
   at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Also, I added the same code to Application_End. At the point that Application_End is being called, System.GetLastError() return nulls.

Upvotes: 2

Views: 1862

Answers (3)

Jeffrey Harmon
Jeffrey Harmon

Reputation: 2437

Brian Main's answer worked perfectly, showing me the message that a file changed in the project folder, which caused a restart.

For those interested, here is the C# version.

var runtime = typeof (HttpRuntime).InvokeMember("_theRuntime", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField, null, null, null);
var shutDownMessage = runtime.GetType().InvokeMember("_shutDownMessage", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null);
var shutDownStack =  runtime.GetType().InvokeMember("_shutDownStack",   BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField, null, runtime, null);

Upvotes: 2

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93444

Your problem is a bug in Visual Studio's "Browser Link" feature. This was fixed in an update. Apply the latest Update (Update 4) to Visual Studio 2013 and your problem should be fixed.

Upvotes: 0

Brian Mains
Brian Mains

Reputation: 50728

I found a trick somewhere on the web (forget where) that you can use reflection to get the reason in the application_end event:

Sub Application_End(sender As Object, e As EventArgs)
        Dim runtime As HttpRuntime = CType(GetType(HttpRuntime).InvokeMember("_theRuntime", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static Or Reflection.BindingFlags.GetField, Nothing, Nothing, Nothing), HttpRuntime)
        Dim shutDownMessage = CType(runtime.GetType().InvokeMember("_shutDownMessage", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.GetField, Nothing, runtime, Nothing), String)
        Dim shutDownStack = CType(runtime.GetType().InvokeMember("_shutDownStack", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance Or Reflection.BindingFlags.GetField, Nothing, runtime, Nothing), String)

       'Log reason

outside of adding IIS tracing, this was a code-specific way that I was able to extract the reason...

Upvotes: 3

Related Questions