问题的主题已经很明确了 - 你有没有想法如何做到这一点?
我一直在查看System.Web.Hosting中的对象,但没有任何突出的东西。
原因是我正在遇到一两个应用程序错误,通常发生在重置时(它们大约间隔25小时,我已将应用程序池重置时间保留默认),因此我想知道它们是否发生在正在关闭的池中的线程上,还是正在启动的池中的线程。
最近我偶然发现了这篇关于Brain.Save()的文章,从托管WCF的角度讲述了需要在Asp.Net中托管WCF服务时如何关闭所有已打开的侦听器,以便新的应用程序域中的WCF引擎能够再次打开它们。
正如文章所示,实现解决方案需要采用IRegisteredObject接口来创建对象实例,调用ApplicationManager.CreateObject
方法,并使用HostingEnvironment.RegisterObject
方法来注册对象(详见MSDN文档)。
当此对象的IRegisteredObject.Stop(bool)
实现被传递false
参数调用时,这意味着应用程序域正在关闭,并且该对象应被取消注册(类似全局释放),并调用HostingEnvironment.UnregisterObject
方法。
如果被传递true
参数调用,则表示您尚未及时取消注册,如果不立即取消注册,系统将自动为您完成。
当发生异常时,我肯定可以使用此机制来确定是否正在终止应用程序域。由于引发异常的对象的特性,如果它不是在关闭过程中,则必须在初始启动期间出现。
同样,我可能会开始将此持久化机制用于其他更复杂的静态信息!
IRegisteredObject
而不是在 global.asax
中实现 Application_Start 和 Application_End 方法的历史和原理:public class RecycleWatcher : IRegisteredObject
{
public static bool IsRecycling { get; private set; }
public void Register()
{
HostingEnvironment.RegisterObject(this);
}
public void Stop(bool immediate)
{
IsRecycling = true;
}
}
启用它
。new RecycleWatcher().Register();
之后只需检查IsRecycling属性,以了解您是否正在回收。
if (RecycleWatcher.IsRecycling) DoSomething();
如果您不确定在应用程序池回收时要执行的操作,但是如果将以下事件处理程序添加到Global.asax,则其中的代码将在关闭应用程序时运行。
protected void Application_End(object sender, EventArgs e)
{
}
host.Run()
方法完成,例如一个全局的CancellationToken
,在主机终止后触发它。 - Lars Kemmann