IIS回收Global.asax

Lie*_*oen 7 iis events recycle global-asax

是否可以在global.asax中捕获循环事件?

我知道Application_End会被触发,但有没有办法知道它是由应用程序池的循环触发的?

thx,Lieven Cardoen又名Johlero

spl*_*tne 7

我在Scott Guthries的博客上发现了这篇文章:

记录ASP.NET应用程序关闭事件

listserv上的某个人最近询问是否有办法找出ASP.NET重新启动应用程序域的原因和时间.具体来说,他正在寻找在生产共享托管环境中触发它们的应用程序的确切原因(是web.config文件更改,global.asax更改,app_code目录更改,目录删除更改,最大值-num-compilations达到了quota,\ 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);
}
Run Code Online (Sandbox Code Playgroud)


spl*_*tne 3

所以,这是一个如何运作的想法。

根据我之前的回答(附加到 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 中检查此文件。如果它不存在,则表明应用程序未以干净的方式终止(或者这是第一次启动)。检查后不要忘记从磁盘中删除该文件。

我自己没有尝试过,但值得一试。