2008-11-16 91 views
6

是否有可能在global.asax中捕获回收事件?IIS回收Global.asax

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

THX,利芬Cardoen又名Johlero

+0

应用可以再循环取决于你的流程的状态非常残酷的事情 - 最糟糕的情况是Win32的::了TerminateProcess被调用。在你的过程中无法捕捉到这样的结果。你想达到什么目的?冲洗一些状态? – stephbu 2008-11-16 17:57:35

回答

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中检查这个文件。如果它不存在,这是一个迹象,表明应用程序是不是在一个干净的方式终止(或者说,它是有史以来第一次它开始)。检查完成后不要忘记从磁盘上删除这个文件。

我没有尝试自己,但它可能是值得一试。

+0

谢谢@splattne的信用... – stephbu 2008-11-17 17:21:02

1

我从来没有尝试过这个自己,但你可以尝试将事件处理程序附加到应用程序域的ProcessExit事件。

... 
AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnExit); 
... 

void OnExit(object sender, EventArgs e) { 
    // do something 
} 

我希望这有助于!

+0

这将捕捉大多数结构化工艺拆散例如 - 但我不确定它会陷入所有的撕裂。 例如http://blogs.msdn.com/jmstall/archive/2006/11/26/process-exit-event.aspx 如果流程似乎被挂起,流程再循环将会终止进程 - 您的处理程序不会被调用。 – stephbu 2008-11-16 17:37:30

6

我发现这篇文章上斯科特Guthries的博客

Logging ASP.NET Application Shutdown Events

有人在邮件列表最近问 是否有办法找出 为何以及何时重新启动ASP.NET 应用程序域。具体来说,他 一直在寻找的 的确切原因是什么触发他们对他 应用在生产共享 托管环境(是它 web.config文件中的变化,一个Global.asax 变化,一个App_Code目录的变化, 一个目录中删除的变化, MAX-NUM-编译达到配额, \ 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); 
} 
0

我更在附加到DomainUnload事件上更成功时,会在AppPool回收和AppPool本身停止时触发。

AppDomain.CurrentDomain.DomainUnload += this.CurrentDomainOnProcessExit;