如何检测当前的应用程序池是否在IIS7.5和Asp.Net 3.5+中清理

And*_*tan 17 asp.net iis iis-7

那么 - 正如问题主题所述 - 关于如何做到这一点的任何想法?

我一直在查看System.Web.Hosting中的对象,但没有什么是突出的.

原因?我收到了一两个应用程序错误,这些错误通常在回收期间发生(它们相隔大约25小时发生,我将应用程序池的回收时间保留为默认值)所以我想知道它们是否发生在正在关闭的池中的线程,或者正在启动(ed/ing)的线程.

And*_*tan 18

我最近偶然发现了关于Brain.Save()的这篇文章,该文章从托管WCF的角度谈论了这个问题(他是Steve Maine - Redmond的连接服务部门的项目经理).

当WCF服务托管在Asp.Net中时,他们需要能够执行此操作,因为他们需要能够关闭任何打开的侦听器,以便新应用程序域中的WCF引擎能够再次打开它们.

正如文章所示,答案是实现IRegisteredObject接口,调用ApplicationManager.CreateObject以创建对象的实例,然后将其注册HostingEnvironment.RegisterObject(所有详细信息都在接口的MSDN文档中).

IRegisteredObject.Stop(bool)使用false作为参数调用此对象的实现时,这是通知应用程序域正在关闭,并且该对象应该被取消注册(有点像全局配置)并且调用HostingEnvironment.UnregisterObject.

当它被调用true时意味着你没有及时取消注册,如果你没有立即取消注册,它将为你完成.

当发生异常时,我当然可以使用这种机制来查明AppDomain是否被杀死.抛出异常的对象的性质意味着如果它不在关闭状态,它必须在初始启动期间.

但是,同样地,我可能会开始考虑这种持久性机制,以获取一些其他更复杂的静态信息!

历史

本文还解释了为什么要使用IRegisteredObject而不是Application_StartApplication_End方法的一些历史和基本原理global.asax:

传统的ASP.NET应用程序可以通过在global.asax中实现Application_Start和Application_Stop等方法来挂钩应用程序生命周期事件(应用程序启动/关闭).但是,global.asax用于应用程序代码.基础架构部件(其中WCF托管系统是其中之一)需要一种机制来挂钩不涉及在global.asax文件中转储基础架构代码的AppDomain生命周期事件.这个空间是为你,用户保留的,并且使用一堆托管goo来污染它将是非常粗鲁的,我们需要让整个工作完成.相反,ASP.NET人员在Whidbey版本中做了一些很棒的工作来打开托管API,让像WCF这样的人能够轻松地以一种对应用程序代码不可见的方式挂钩这些生命周期事件.


小智 8

您可以检查System.Web.Hosting.HostingEnvironment.ShutdownReason的值,当应用程序池未处于关闭/回收过程中时,它将具有None 的ShutdownReason.


Wol*_*lf5 5

添加实际代码来执行此操作:

public class RecycleWatcher : IRegisteredObject
{
    public static bool IsRecycling { get; private set; }

    public void Register()
    {
        HostingEnvironment.RegisterObject(this);
    }
    public void Stop(bool immediate)
    {
        IsRecycling = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后通过运行启用它

new RecycleWatcher().Register();
Run Code Online (Sandbox Code Playgroud)

之后,只需检查 IsRecycling 的该属性即可知道您是否正在回收。

if (RecycleWatcher.IsRecycling) DoSomething();
Run Code Online (Sandbox Code Playgroud)