关闭FCNs(文件修改监控)

也许你知道,修改站点的某些特定文件和目录会导致整个站点重启或者重新编译。也许你不注意,你不会知道删除或重命名站点下的任意目录,会导致整个站 点重启(添加目录并不会)。这个问题其实是很多Session丢失的根源,比如《关于 ASP.NET 2.0的目录结构变化导致Session丢失的问题》,同样你还可以找到很多这样的例子。

这个其实是 ASP.NET 2.0的一个“精心”设计,因为在很多情况下。ASP.NET会缓存很多资源,而如果没有监控目录的变动的话,那么有些已删除的资源就有可能仍然被使用 着,造成其它不必要的资源泄露。通过这篇文章我们可以找到可能导致站点重启的一些条件,其中的第一条就是删除或重命名目录会导致站点重启。

这 个问题早在ASP.NET 2.0刚发布的时候就被发现,并且已经有了专门的讨论《Deleting ASP.NET 2.0 Application Sub-Directories Shuts Down the AppDomain》,在文中也提了一种解决方案,但是做法太过复杂。最理想的方案是,有相关的补丁来解决这个问题,幸运的 是,我们可以通过这里找到这个补丁,并且介绍如何配置来解决这个问题。

解决方案是:监控目录删除或重命名的机制 叫:File Change Notifications (FCNs),这个补丁就是用来设置FCNS禁用或启用的开关,我们只要把FNCS禁用就可以避免这个问题。

做法:现在的ASP.NET 2.0已经到了SP2,我们不需要单独去安装这个补丁。我们只需要在注册表在做一步操作即可解决这个问题。在HKLM\Software \Microsoft\ASP.NET 添加一个名为:FCNMode 的DWORD值,默认它应该是不存在的,它的值含义为:

Does not exist
This is the default behavior. For each subdirectory, the application will create an object that will monitor the subdirectory.

0 or greater than 2
This is the default behavior. For each subdirectory, the application will create an object that will monitor the subdirectory.

1
The application will disable File Change Notifications (FCNs).

2
The application will create one object to monitor the main directory. The application will use this object to monitor each subdirectory.

我们将它的值设为1即可禁用FCNS。更为详细的可以参 考:http://support.microsoft.com/kb/911272

退出注册表,重启IIS,问题即可解决。

说明一下:Session丢失 只是AppDomain重启的一个副作用,并不是本文的重点,只是为了方便别人查找相关问题时的一个标题优化。另外导致站点重启的原因有很多种,可以参考 上文给出的链接,这里不再遨述。

再次说明一下:如果你禁用 了FCNs,那么不管你是修改了Web.config,还是BIN目录,都不会引起整个站点的重启。我想这个也会相应的给我们带来一些新的问题,比如缓存 过期的问题。至于是否禁用,大家自己选择吧。:(

 

补充,通过代码可 以去除目录的改动监控,同时不影响bin目录和web.config改动时,程序需要的重启。

public class StopFileMonitorModule : IHttpModule
{
#region IHttpModule Members

public void Dispose()
{

}

public void Init(HttpApplication context)
{
PropertyInfo p = typeof(System.Web.HttpRuntime).GetProperty("FileChangesMonitor", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
object o = p.GetValue(null, null);
FieldInfo f = o.GetType().GetField("_dirMonSubdirs", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.IgnoreCase);
object monitor = f.GetValue(o);
MethodInfo m = monitor.GetType().GetMethod("StopMonitoring", BindingFlags.Instance | BindingFlags.NonPublic);
m.Invoke(monitor, new object[] { });

}

#endregion
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值