如果遭遇ASP.Net应用程序莫名其妙退出问题,可以在Global.asax中添加下列代码记录Application Pool退出原因
void Application_End(object sender, EventArgs e)
{
HttpRuntime runtime = (HttpRuntime) typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime"
, BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField
, null
, null
, null
);
if (runtime == null) return;
string shutDownMessage = (string)runtime.GetType().InvokeMember("_shutDownMessage"
, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField
, null
, runtime
, null
);
string shutDownStack = (string)runtime.GetType().InvokeMember("_shutDownStack"
, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField
, null
, runtime
, null
);
EventLog log = new EventLog();
log.Source = "XXX";
log.WriteEntry(String.Format("\r\n\r\n_shutDownMessage={0}\r\n\r\n_shutDownStack={1}"
, shutDownMessage
, shutDownStack
)
, EventLogEntryType.Warning
);
}
此代码将退出的原因记录到了XXX这个 Event Source, 所以需要在服务器上创建此 Event Source.
eventcreate /ID 1 /L APPLICATION /T INFORMATION /SO XXX /D "XXX"
当Application Pool正常退出时,日志中就会记录有Application Pool退出的原因。无外乎下面几种情况:
1. web.config被修改 / 2. 即时编译的*.cs文件被修改(一般在App_Code中) / 3.Bin目录被更新 / 4.*.aspx,*.ascx,*.master文件被修改的个数超过阀值 / 5. 长时间的Idle超过阀值
下面的日志显示的是由于App_Code目录被修改导致的退出
The following information was included with the event:
_shutDownMessage=Change Notification for critical directories.
App_Code dir change or directory rename
HostingEnvironment initiated shutdown
Change Notification for critical directories.
App_Code dir change or directory rename
HostingEnvironment caused shutdown
_shutDownStack= at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
at System.Environment.get_StackTrace()
at System.Web.Hosting.HostingEnvironment.InitiateShutdownInternal()
at System.Web.HttpRuntime.ShutdownAppDomain(String stackTrace)
at System.Web.HttpRuntime.OnCriticalDirectoryChange(Object sender, FileChangeEvent e)
at System.Web.FileChangesMonitor.OnCriticaldirChange(Object sender, FileChangeEvent e)
at System.Web.DirectoryMonitor.FireNotifications()
at System.Web.Util.WorkItem.CallCallbackWithAssert(WorkItemCallback callback)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
the message resource is present but the message is not found in the string/message table
同时最好加上日志记录Application的启动事件。
protected void Application_Start(object sender, EventArgs e)
{
EventLog log = new EventLog();
log.Source = "XXX";
log.WriteEntry("Application Pool Starting..." , EventLogEntryType.Information);
}
通过 eventvwr, 可以分析Application Pool重启的原因。如果Application Pool是由于崩溃导致异常退出,这个时候Application_End是不会被触发的。但同时在 ASP.Net的系统日志中还是能够查到异常退出的原因。