IIS网站文件结构修改导致服务器重启的解决办法

  组内正在做一个项目,用的是ASP.NET的那一套。项目需要将MP3音频文件解压缩,提取其系数,这时我们用的是一个外部的EXE可执行文件。最令人头 痛的是,每当页面执行到一半的时候就会抛出一个“线程中止异常”(System.Threading.ThreadAbortException)。页面 提示如下:

“/”应用程序中的服务器错误。
正在中止线程。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。

异常详细信息: System.Threading.ThreadAbortException: 正在中止线程。
源错误:
执行当前 Web 请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息。
堆栈跟踪:
[ThreadAbortException: 正在中止线程。]
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +303
   System.Web.ApplicationStepManager.ResumeSteps(Exception error) +762
   System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +211
   System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr) +452

  下班时,我在一个国外站点找 到了解决方案。有意思的是,这位外国朋友说 “I killed hours playing with timeouts and configs before finding the solution. ” (我花好几小时和“超时”属性和配置文件玩在一起)。我不禁感叹“play with”这个动词短语用得精巧。
  言归正传,由于出错的时间点是2分钟,和这位外国朋友一样,我马上被误导到“Timeout”设置。于是,我把文件上传、页面处理、IIS请求超时、会话超时等多处设置都改成了好几十分钟。错误照旧。直到看了这个网页以后才发现,事情根本不是这样的。
   问题的起因是IIS有一个“File Change Notifications(FCNs)”,ASP 2.0所谓“更安全、更稳定”的新特性,它是 用来监视Web站点目录下的文件结构或内容“是否被大量改变”。如果站点被改变,则自动重启站点。这个特性主要考虑到,ASP.NET会缓存很多资源,而 如果没有监控目录的变动的话,那么有些已删除的资源就有可能仍然被使用着,造成其它不必要的资源泄露。
   我立刻联想到先前也出过且一直没解决的一个问题:删除或重命名站点下的任意目录或XML文件会导致丢失Session,从Global.asax(据说 是一个很糟糕的设计,但我觉得还OK,长处短处是并存的。)的运行日志看出,Web程序经常莫名其妙重启。在Visual Studio 2008调试时 使用的自带轻量级Web服务器不会有这些问题。问题就在这里。
  了解事件的起因,我们来谈一谈解决之道。直观的思路就是把FCNs禁用。估计微软后来也意识到了FCNs并非只有好处没有坏处,所以发布了一个ASP.NET 2.0 SP2,提供禁用FCNs功能。然后你有三种途径:
  (1)修改注册表
  在HKLM\Software\Microsoft\ASP.NET下添加一个名为:FCNMode的DWORD值,默认它应该是不存在的,它的值含义为:
  不存在,或不等于1且不等于2:这是默认行为。对每一个子目录,应用程序会创建一个对象监视这个目录。
  值为1:应用程序将禁用FCNs。
  值为2:应用程序将创建一个对象监视主目录,应用程序用这个对象监视每个子目录。
  显然,FCNMode的值设为1即可禁用FCNS。最后,重启IIS。
  (2)修改代码
  在Global.asax(或其.cs文件)增加代码如下,就可以关掉FCNs)。

    using System.Reflection;
    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[] { });

  其它诸如放在IHttpModule方法,和Global.asax本质是一样的,这个属于如何使用HttpModule功能的范畴,这里不展开叙述。
  (3)良好的编程习惯
  把经常修改的目录移到外面去,并做一个页面用于下载该文件夹下的文件,可以提高安全性。例如管理信息系统的“用户目录”等。这个方法的优点是,可以避免不必要的资源泄露。

http://www.cnblogs.com/LoriMoon/archive/2010/11/21/1883521.html

 

posted @ 2013-04-15 21:30  shiningrise  阅读(485)  评论(0编辑  收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css