IIS回收Global.asax
-
08-07-2019 - |
题
是否可以在global.asax中捕获循环事件?
我知道Application_End会被触发但有没有办法知道它是由应用程序池的循环触发的?
thx,Lieven Cardoen又名Johlero
解决方案
所以,这是一个如何运作的想法。
基于我的上一个答案(附加到AppDomain.CurrentDomain.ProcessExit)和 stephbu 的评论:
这将捕获大多数结构化过程 拆卸,例如 - 但我不确定 它将陷入所有的撕裂。例如 http://blogs.msdn.com/ jmstall /存档/ 2006/11月26日/流程出口event.aspx 进程回收将终止进程 如果它似乎挂了 - 你的处理程序 不会被召唤。
我建议遵循以下策略:
在(常规)ProcessExit处理程序中(我们假设在应用程序池回收时不会调用它),将一些文件写入磁盘,如<!>“; app_domain_end_ok.tmp
<!>”;
然后在global.asax的Application_Start中检查此文件。如果它不存在,则表明应用程序未以干净的方式终止(或者它是第一次启动)。检查后不要忘记从磁盘中删除此文件。
我自己没有尝试过,但值得一试。
其他提示
我在 Scott Guthries的博客上发现了这篇文章:
listserv上有人最近问过 是否有办法弄清楚 ASP.NET重启的原因和时间 应用领域。具体来说,他 正在寻找确切的原因 是什么引发了他们 在生产中共享应用程序 托管环境(是一个 web.config文件更改,global.asax 更改,app_code目录更改, 目录删除更改, max-num-compilations达到配额, \ bin目录更改等)。
托普在我的团队中表现得很酷 他编写的代码片段使用 一些漂亮的私人反思技巧 捕获并记录此信息。 它很容易重复使用和添加 进入任何应用程序,并可以使用 在任何地方记录信息 想要(下面的代码使用NT事件 登录保存<!>#8211;但你可以这样 轻松将其发送到数据库或通过 发送电子邮件给管理员)。代码有效 同时使用ASP.NET V1.1和ASP.NET V2.0。只需添加System.Reflection和 System.Diagnostics命名空间到你的 Global.asax类/文件,然后添加 这个Application_End事件 代码:
public void Application_End() {
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);
if (!EventLog.SourceExists(".NET Runtime")) {
EventLog.CreateEventSource(".NET Runtime", "Application");
}
EventLog log = new EventLog();
log.Source = ".NET Runtime";
log.WriteEntry(String.Format(
"\r\n\r\n_shutDownMessage={0}\r\n\r\n_shutDownStack={1}",
shutDownMessage, shutDownStack),
EventLogEntryType.Error);
}
我自己从未尝试过,但您可以尝试将事件处理程序附加到AppDomain的ProcessExit事件。
...
AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnExit);
...
void OnExit(object sender, EventArgs e) {
// do something
}
我希望这有帮助!
我在附加到DomainUnload事件时更成功,它在AppPool回收和AppPool本身停止时触发。
AppDomain.CurrentDomain.DomainUnload += this.CurrentDomainOnProcessExit;