We have an ASP.NET MVC 4 application that links to legacy native code. The problem is that this legacy code has global statics that are constructed at startup, but because native code knows nothing about App Domains, that code is not re-initialized when the App Domain is reloaded. This causes incorrect behaviour or crashes in our app until the Application Pool process is restarted.
Because of this, I would like to force the Application Pool to recycle whenever our application's App Domain is recycled. Is there a setting in IIS for this, or is there code that I can call in my application as the domain is being unloaded?
Some info on my setup,
Update
Based on the answer below, I hooked up to the AppDomain unload event and used code similar to the following to recycle the Application Pool.
try
{
// Find the worker process running us and from that our AppPool
int pid = Process.GetCurrentProcess().Id;
var manager = new ServerManager();
WorkerProcess process = (from p in manager.WorkerProcesses where p.ProcessId == pid select p).FirstOrDefault();
// From the name, find the AppPool and recycle it
if ( process != null )
{
ApplicationPool pool = (from p in manager.ApplicationPools where p.Name == process.AppPoolName select p).FirstOrDefault();
if ( pool != null )
{
log.Info( "Recycling Application Pool " + pool.Name );
pool.Recycle();
}
}
}
catch ( NotImplementedException nie )
{
log.InfoException( "Server Management functions are not implemented. We are likely running under IIS Express. Shutting down server.", nie );
Environment.Exit( 0 );
}
Configuring Auto-Start with IIS ManagerIn the Connections pane, select the Application Pools node, revealing the Application Pools pane in the main view. Select the application pool for which you wish to enable Auto-Start. Locate the Start Mode option under the General group and set it to AlwaysRunning. Click OK.
Does IISRESET recycle the application pools? The correct answer is no. Instead, IISRESET causes the shutdown of all active IIS worker processes, kills them if they do not stop in time.
A simplified VB version of the code you shared. This version uses a For loop instead of a LINQ query. Also, in order to use Microsoft.Web.Administration, you must import the DLL from c:\windows\system32\inetsrv
Imports System.Diagnostics
Imports Microsoft.Web.Administration
Dim pid As Integer = Process.GetCurrentProcess().Id
Dim manager = New ServerManager()
For Each p As WorkerProcess In manager.WorkerProcesses
If p.ProcessId = pid Then
For Each a As ApplicationPool In manager.ApplicationPools
If a.Name = p.AppPoolName Then
a.Recycle()
Exit For
End If
Next
Exit For
End If
Next
A more brutal approach is to call Process.GetCurrentProcess().Kill() Not very graceful, but if your site has its own app pool and you don't care any current requests being brutally stopped, that's quite effective!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With