当创建、重命名或删除文件夹时,ASP.NET 将重新启动。

17

更新 -- 复制问题的过程:

1)在c:\projects\restart-demo创建一个网站项目。

2)添加默认的web.config和一个虚拟的aspx页面test.aspx

3)将IIS映射到根目录c:\projects\restart-demo

4)使用perfmon,健康监测,跟踪全局.asax应用程序结束等方式监视应用程序重启。

5)在浏览器中请求页面http://localhost/test.aspx

应用程序开始

6)创建新文件夹c:\projects\restart-demo\asdf

应用程序结束

7)在浏览器中请求页面http://localhost/test.aspx

应用程序开始

8)将文件夹c:\projects\restart-demo\asdf重命名为c:\projects\restart-demo\asdf1

应用程序结束

结束更新

我们正在使用后端CMS在ASP.NET站点中生成文件和文件夹。

用户能够创建/修改/删除文件并将其推送到Web Farm。

我们注意到一个问题:

当用户创建、重命名或删除文件夹时,它会导致App Domain重启。因此,会丢失所有的session,cache等。

注意,它并不需要是特殊的文件夹,如/bin或/App_Code。

有没有办法阻止这种行为?

这真的会妨碍性能,原因如下:

  • 缓存在应用程序域重启时被清空
  • 应用程序域需要在重启后重新构建

1
这种情况是100%发生,还是只在创建一定数量的时候发生,比如每15次更改? - Nick Craver
您所描述的行为并不典型。您能否提供更多上下文信息,比如代码? - Nathan Taylor
@Nick:这种情况每次都会发生。 - frankadelic
@Nathan,我已发布了复制问题的步骤。 - frankadelic
假设接受的答案解决了您的问题。您能告诉我在哪里添加下面的代码以及从哪里调用它吗?我尝试在我的Global.asax和控制器文件中这样做,但没有成功。如果您能编辑您的问题并将该信息放在末尾,那将是非常好的 :) - TechnicalSmile
5个回答

15

将以下代码添加到Global.asax文件的Application_Start()方法中,似乎可以解决该问题:

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[] { }); 

http://dotnetslackers.com/Community/blogs/haissam/archive/2008/11/12/disable-session-expiration-when-using-directory-delete.aspx

通过这些更改,我可以创建/修改/删除文件夹而不会导致应用程序重新启动。
不清楚这是否是最佳解决方案-- 不知道调用StopMonitoring是否会产生意外的副作用。

1
好像是个巨大的黑客攻击,但如果它能够工作,我猜你别无选择。感谢你回报解决方案。 - mxmissile
此外,这里还有一个更完整的示例,展示如何实现这一点:http://www.aaronblake.co.uk/blog/2009/09/28/bug-fix-application-restarts-on-directory-delete-in-asp-net/ - user87453

9
也许有点晚了,但是将临时文件存储和处理在应用程序的wwwroot之外的不同文件夹中也可以解决问题。

2
默认情况下,一个asp.net应用程序在其虚拟目录中的文件更改每15次时会重新启动,这是为了抵消部分重新编译及其内存负载与整体性能之间的差异...您可以更改此行为,但内存使用可能会上升,而随着时间的推移,性能也会下降。
要做到这一点,请设置编译元素上的numRecompilesBeforeAppRestart属性,您的web.config将有一个类似于以下内容的元素:
<configuration>
  <system.web>
    <compilation numRecompilesBeforeAppRestart="15">

默认值为15,您可以将其更改为任何您想要的值,请阅读链接获取更多信息。然而,这样做是有原因的,不建议在应用程序的虚拟目录中放置动态内容,最好将其放在旁边或其他地方。

没有重新编译任何东西。我只是创建空文件夹。 此外,我调整了numRecompilesBeforeAppRestart,并且每次创建/修改/删除文件夹时仍然触发Application_End事件。 - frankadelic
@frankadelic - 你能否提供一些文件夹的示例,这些文件夹是相对于根目录而创建的? - Nick Craver
添加复现问题的步骤。 - frankadelic
@frankadelic - 您看到这个问题是在哪个操作系统上?FCN功能不同,因此在这种情况下很重要。 - Nick Craver
我已经在Windows XP(IIS 5.1)和Windows 2008(IIS7)上复制了这个问题。 - frankadelic

2
"fcnMode="Disabled"添加到<httpRuntime>设置中的web.config可以在修改Web根文件夹内容时禁用AppDomain回收。

0

启用 ASP.NET 健康监控 并查看事件日志,以了解应用程序域为何重新启动。


我敢打赌这是因为你使用了网站项目,而不是Web应用程序项目。尝试使用Web应用程序项目重现此问题。

另外,您是否运行任何反病毒或索引软件?这类软件会注意到文件夹何时被创建和/或修改。


事件消息:应用程序正在关闭。原因:未知。 - frankadelic
谢谢您的查看。在这种情况下,我建议您寻找防病毒软件和可能的索引软件。 ASP.NET不会在创建文件夹时导致重启 - 其他问题导致了重启。 - John Saunders
在没有杀毒软件和索引服务的单独机器上尝试了这个。我仍然发现Application_End正在触发。我已经在3台不同的机器上进行了测试。 - frankadelic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接