在遗留c#代码中查找文件锁
本文关键字:查找 文件锁 代码 | 更新日期: 2023-09-27 17:51:24
我有一个有趣的问题——我继承了一个很大的代码库(棕色字段)。
应用程序按时间表运行,并获取大量数据文件(文本),处理它们,然后导出报告并清理。
已经发现了一个错误,即在尝试清理之后,一些文件保留在locked
状态,即使所有文件活动早已超出范围。这将阻止应用程序在清理过程中删除它们。
在这个应用程序中使用了数百个IO和流对象等,我想找出从哪里开始查找以节省检查它们使用的每个实例。
在c#托管代码中,有哪些很好的工具可以用来研究文件锁?你是如何使用它们的?
当您忘记处置拥有文件句柄的父对象时,通常会发生这种情况。例如,你忘记对一个文件流调用Close/Dispose。然后,当文件句柄在下一次完整GC期间不再被引用时,终结器将清理它们。
你可以用Windbg检查你是否在结束队列中有SafeFileHandles准备结束。一个可以跟踪这些事情的分析器是YourKit,当你启用探测时,它也可以搜索在终结器中关闭的文件,并为你提供创建调用堆栈,使你能够在代码中搜索有问题的行。检查YourKit的process Inspection选项卡以查找探针检查。
您可以使用SysInternals中的ProcMon监视文件访问(读/写)。它不是c#特有的,而是一个通用的工具,可以用于许多其他事情。注意,您可以将结果导出为csv,稍后再进行调查。
你可以使用以下指南之一:
- 详细的Windows I/O:进程监控-如何做简单的文件监控。
- 使用进程监视器来监视文件访问-更详细的指南,解释如何将结果导出为csv,以便稍后进行调查。
我没有找到任何用于此目的的东西,所以如果我是你,我会继承使用的蒸汽,并将其包装为日志逻辑。
这个日志流对象,例如命名为LogStream
,将在每个方法入口之前写日志,调用base.function()
并在完成时写另一个日志。
这样你就可以监视你想要的文件访问。例如,使用Guid.NewGuid()
记录每个流实例的Id,使用System.Threading.Thread.CurrentThread.ManagedThreadId
记录线程Id等。
通过这种方式,您可以识别实例并慢慢调查调用。
首先要检查流打开和关闭的数目是否相等,如果出现异常,可能会避免Dispose()
调用中的一个。