C#,Windows 7:如何可靠地检查进程是否仍在写入文件

本文关键字:是否 进程 文件 检查 Windows 何可 | 更新日期: 2023-09-27 18:26:49

我有一个C#实用程序,它需要在另一个进程释放特定文件后立即执行一些操作,即该进程停止写入该文件。我正在使用下面的代码,但它在Windows7系统上的表现不一致。

private static bool FileWritten(string filename)
    {
        try
        {
            using (FileStream inputStream = File.Open(filename, FileMode.Open,
                        FileAccess.Read,
                        FileShare.None))
            {
                return true;
            }
        }
        catch (IOException e)
        {
            return false;
        }
    }

有时它会返回false,即使文件似乎已经发布。我在while(true)循环中调用FileWritten(),只要它返回false,就会一直检查调用FileWriten()的情况,然后在最长时间后退出。调试这一点很困难,因为它在调试器下似乎可以很好地工作(即,一旦文件真正发布,它就会返回true),但当我直接启动代码时,它就不起作用了。此外,即使添加调试打印似乎也会影响其行为。

是否有更可靠的方法来检查文件是否已写入并发布,这将在Win 7上运行,最好也在Win XP上运行?

C#,Windows 7:如何可靠地检查进程是否仍在写入文件

这个问题没有完美的解决方案。

即使你的代码在Windows7上运行良好,仍然会有竞争条件。

假设FileWritten在某个时间点返回false。您的代码假定该文件不再被锁定并继续执行。。。但该文件可能会在下一毫秒再次锁定,下次您尝试访问该文件时,它将抛出异常。。。

难道你不能试着访问你的文件,如果你不能访问它,就抓住异常吗?然后你可以等待一段时间,然后再试一次。它将比试图返回布尔值的函数更干净,该布尔值指示文件是否被进程使用。

您可以使用FileSystemWatcher来侦听文件上的事件。一些选项将允许您查看文件是否已更改。每当收到文件更改的通知时,您可以使用爆米花效果(重置计时器)使线程睡眠一定时间。然后执行你的代码(但实际上让它在你有锁的时候在True路径中完成你的工作)。如果文件仍然被锁定,则会出现错误,请多睡一会儿等待事件。

除了让其他进程在完成后重命名/复制原始文件到新位置之外,没有通用的API可以在其他进程删除文件后立即为您提供文件锁定。