IIS 回收全局.asax

发布于 2024-07-09 04:11:39 字数 132 浏览 9 评论 0原文

是否可以在 global.asax 中捕获回收事件?

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

谢谢,Lieven Cardoen 又名 Johlero

Is it possible to catch an recycle event in the global.asax?

I know Application_End will be triggered but is there a way to know that it was triggered by a recycle of the application pool?

thx, Lieven Cardoen aka Johlero

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

扬花落满肩 2024-07-16 04:11:39

我在 Scott Guthries 的博客上找到了这篇文章:

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

列表服务器上有人最近问过
是否有办法弄清楚
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);
}

I found this article on Scott Guthries's blog:

Logging ASP.NET Application Shutdown Events

Someone on a listserv recently asked
whether there was a way to figure out
why and when ASP.NET restarts
application domains. Specifically, he
was looking for the exact cause of
what was triggering them on his
application in a production shared
hosted environment (was it a
web.config file change, a global.asax
change, an app_code directory change,
a directory delete change,
max-num-compilations reached quota,
\bin directory change, etc).

Thomas on my team has a cool
code-snippet that he wrote that uses
some nifty private reflection tricks
to capture and log this information.
It is pretty easy to re-use and add
into any application, and can be used
to log the information anywhere you
want (the below code use the NT Event
Log to save it – but you could just as
easily send it to a database or via an
email to an admin). The code works
with both ASP.NET V1.1 and ASP.NET
V2.0.

Simply add the System.Reflection and
System.Diagnostics namespaces to your
Global.asax class/file, and then add
the Application_End event with this
code:

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);
}
蒲公英的约定 2024-07-16 04:11:39

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

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

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

So, here is an idea how this could work.

Based on my previous answer (attach to AppDomain.CurrentDomain.ProcessExit) and stephbu's comment:

This will trap most structured process
teardowns e.g. - but I'm not sure that
it will trap all tear downs. e.g.
http://blogs.msdn.com/jmstall/archive/2006/11/26/process-exit-event.aspx
Process recycle will kill the process
if it seems to be hung - your handler
wouldn't get called.

I suggest following strategy:

In the (regular) ProcessExit handler (which we suppose will not be called on a application pool recycling), write some file to disk like "app_domain_end_ok.tmp".

Then in the Application_Start of your global.asax check for this file. If it doesn't exist it is a sign that the application was not terminated in a clean way (or that it is the first time ever it started). Don't forget to delete this file from disk after the check.

I didn't try that myself, but it could be worth a try.

逆蝶 2024-07-16 04:11:39

我自己从未尝试过,但您可以尝试将事件处理程序附加到 AppDomain 的 ProcessExit 事件。

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

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

我希望这有帮助!

I've never tried this myself, but you could try to attach an event handler to the ProcessExit event of the AppDomain.

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

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

I hope this helps!

青萝楚歌 2024-07-16 04:11:39

我在附加到 DomainUnload 事件方面更加成功,它是在 AppPool 回收和 AppPool 本身停止时触发的。

AppDomain.CurrentDomain.DomainUnload += this.CurrentDomainOnProcessExit;

I was much more successful with attaching to DomainUnload event, it is triggered on AppPool recycle and stoppage of the AppPool itself.

AppDomain.CurrentDomain.DomainUnload += this.CurrentDomainOnProcessExit;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文