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