【问题标题】:How to Close a File During App Pool Recycle如何在应用程序池回收期间关闭文件
【发布时间】:2019-04-12 11:52:05
【问题描述】:

我有一个在其自己的应用程序池中运行的应用程序,该应用程序经常写入文本日志文件。当 29 小时固定回收命中时,我通常会遇到问题,因为新进程启动时旧进程仍然存在。这会导致“无法打开文件,因为它正在被另一个进程使用。”

首先,我只是尝试将 禁用重叠循环 设置为 True,但这会使我的服务中断 90 秒或更长时间,这并不好。如果我减少 关闭时间限制,我想这会有所帮助,但我不希望立即终止进程。

我尝试在 Global.asax 中设置 Application_End 处理程序,但我发现它几乎从未被调用,因为(我认为)我的进程仍在某处运行线程(可能是日志记录进程)。

我尝试了Application_Disposed,但到目前为止,当 IIS 在关闭时间到期后终止进程时,它不会被调用,如果我回到重叠回收可能为时已晚,我认为这是更可取的。

我需要的是来自 IIS 的“嘿,我希望你停下来”的信号,它让我可以立即关闭日志文件,但它似乎不存在。

任何建议将不胜感激。

【问题讨论】:

  • IIS 不会关闭您的 Web 应用程序(调用 Application_End),直到新的 Web 应用程序运行,这就是重叠回收在幕后工作的方式。因此,您不应该期望 IIS 给您“信号”。通常应该是您的 Web 应用程序通知自身的其他副本,IIS 启动了一个新副本。或者您的 Web 应用程序的新副本实现了一些简单的重试机制来写入文件(因为一旦 IIS 关闭了应用程序的旧副本,该文件就是可写的)。
  • 我知道在 IIS 真正要结束我的应用程序之前,我不会得到 Application_End ——尽管大多数时候即使那个调用似乎也不会发生。我希望还有其他电话。坦率地说,添加某种代码来查找我的旧应用程序在哪个 W3WP 中运行并设置一些 IPC 通道来与之通信似乎需要做很多工作。在这一点上,我会考虑完全关闭回收——这对我没有任何帮助。

标签: iis application-pool recycle


【解决方案1】:

问题出在您的应用本身而不是IIS

只需Disposed 调用或写入文本文件后的对象即可避免此问题。

我以前也遇到过这种情况。我还写入一个文本文件以获取日志,然后出现错误"can't open the file because it's in use by another process.",但是当我disposed the object 不仅仅是单词disposed 时,您必须仔细检查它以进行适当处理。

一切都消失了,可以正常运行应用了。

希望对你有帮助

【讨论】:

  • 在某些场景下可能会起作用,但是你一般不能每次在生产服务器上写东西时打开和关闭文件,这样会太慢。应该对重叠的场景做一些特殊的处理,或者缓存写不频繁重试。
  • 我的经验是经常写日志,但到目前为止我没有再次遇到任何错误。我也在像 IIS 这样的服务器端部署项目。在我第一次使用它时,如果觉得我很烦("can't open the file because it's in use by another process.)但是当我修改和检查代码时,幸运的是它现在运行良好。从那时起已经将近 5 年了,我所有的项目都运行良好,所以我怎么能说这是 IIS 方面的错误或其他东西。您暂时必须做的解决方案是在Task Manager 中删除它,但这不是一个更好的解决方案。
  • 我正在使用一个自定义日志类,该类用于我的产品中的多个服务,包括 Web 和 Windows 服务。事实上,默认情况下,我大约每 30 秒缓存和写入一次,但在一些更繁忙的服务中,我可能会在几个小时内写入数百万行,所以我对关闭/处理流对象持谨慎态度。在这一点上,我正在考虑要么完全关闭循环,要么让关闭时间非常短,并选择凌晨 2:00 而不是 29 小时的循环时间。
猜你喜欢
  • 1970-01-01
  • 2011-04-15
  • 1970-01-01
  • 2020-02-14
  • 1970-01-01
  • 2011-09-08
  • 2015-01-07
  • 2012-06-05
  • 2011-10-17
相关资源
最近更新 更多