创建、重命名或删除文件夹时 ASP.NET 重新启动
Posted
技术标签:
【中文标题】创建、重命名或删除文件夹时 ASP.NET 重新启动【英文标题】:ASP.NET restarts when a folder is created, renamed or deleted 【发布时间】:2011-01-15 23:16:55 【问题描述】:更新——复制问题的过程:
1) 在 c:\projects\restart-demo
创建网站项目2) 添加默认 web.config 和一个虚拟 aspx 页面 test.aspx
3) 映射 IIS 以指向根文件夹 c:\projects\restart-demo
4) 使用 perfmon 监控应用程序重启、健康监控、跟踪 global.asax Application_End 等。
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 站点中生成文件和文件夹。
用户可以创建/修改/删除文件并将它们推送到网络农场。
我们注意到的一个问题:
当用户创建、重命名或删除文件夹时,会导致App 要重新启动的域。作为结果, session、缓存等全部丢失。
请注意,它也不需要是像 /bin 或 /App_Code 这样的特殊文件夹。
有没有办法防止这种行为?
这确实会影响性能,原因有两个:
应用域重启时缓存被转储 重启后需要重新构建应用域【问题讨论】:
这种情况是否 100% 发生,或者说,创建了一定数量,例如每 15 次更改? 您描述的行为并不典型。你能给我们一些更多的上下文信息代码吗? @Nick:这种情况每次都会发生。 @Nathan,我已经发布了重现问题的步骤。 假设接受的答案解决了您的问题。你能告诉我你在哪里添加下面的代码以及你从哪里调用它。我尝试在我的 Global.asax 和控制器文件中这样做,但没有任何运气。如果您可以编辑您的问题并将该信息放在最后,那就太好了:) 【参考方案1】:启用 ASP.NET Health Monitoring 并查看事件日志以了解 AppDomain 重新启动的原因。
我敢打赌,这是因为您使用的是网站项目,而不是 Web 应用程序项目。尝试使用 Web 应用程序项目重现这一点。
另外,您是否正在运行任何防病毒或索引软件?此类软件会在创建和/或修改文件夹时发出通知。
【讨论】:
事件消息:应用程序正在关闭。原因:未知。 感谢您的检查。在这种情况下,我建议您寻找防病毒软件,也许还有索引软件。每当创建文件夹时,ASP.NET 都不会导致重新启动 - 其他东西 is. 在没有防病毒软件和索引服务禁用的单独机器上尝试了这个。我仍然发现 Application_End 正在触发。我已经在 3 台不同的机器上进行了测试。【参考方案2】:默认情况下,asp.net 应用程序将在其虚拟目录中的文件更改时每 15 次重新启动一次,这是为了超过部分重新编译及其内存权重与整体性能的关系...您可以更改此行为,但内存使用量可能会增加并且性能会随着时间的推移而下降。
为此,请设置numRecompilesBeforeAppRestart attribute on the compilation element,您的 web.config 将具有这样的 en 元素:
<configuration>
<system.web>
<compilation numRecompilesBeforeAppRestart="15">
默认值为 15,您可以将其更改为您想要的任何值,请阅读链接了解更多信息。但是,这种方式是有原因的,不建议将您的动态内容放在应用的虚拟目录中,最好将其放在旁边或完全放在其他地方。
【讨论】:
没有重新编译。我只是在创建空文件夹。此外,我已经调整了 numRecompilesBeforeAppRestart 并且 Application_End 仍然会在每次创建/修改/删除文件夹时触发。 @frankadelic - 您能否更新一个与根目录相关的几个正在创建的文件夹的示例? 添加了复制问题的步骤。 @frankadelic - 什么操作系统看到这个? FCN 功能不同,所以在这种情况下很重要 我已经在 Windows XP (IIS 5.1) 和 Windows 2008 (IIS7) 上复制了这个问题。【参考方案3】:当添加到 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 用于报告您的解决方案。 这里还有一个更完整的示例说明如何执行此操作:aaronblake.co.uk/blog/2009/09/28/…【参考方案4】:可能有点晚了,但是在应用程序 wwwroot 之外的不同文件夹中存储和处理临时文件也可以解决问题。
【讨论】:
【参考方案5】:将"fcnMode="Disabled"
添加到web.config
中的<httpRuntime>
设置会在Web 根文件夹的内容发生更改时禁用AppDomain 回收。
【讨论】:
以上是关于创建、重命名或删除文件夹时 ASP.NET 重新启动的主要内容,如果未能解决你的问题,请参考以下文章
Linux编程 5 (目录重命名与移动mv,删除文件rm,目录创建mkdir删除rmdir,查看file,cat,more,tail,head)