7

我需要让 FileSystemWatcher 在无限循环中运行以监视文件的更改,但是该文件每隔几天才会更改一次,并且可能每周更改一次。在FileSystemWatcher的 MSDN 示例中,有一个循环,而用户没有在控制台输入 q:

while(Console.Read()!='q');

我不希望它一直可用,所以它不会被意外杀死——它必须在没有用户干预的情况下无限循环运行。我是否必须将循环更改为

while (true);

所以线程不退出?仅此一项并不理想,因为它将与 CPU 挂钩 - 添加Thread.Sleep调用将消除 CPU 负载,在这种情况下,可能会长时间休眠,因为文件很少更改。这是最好的方法吗?我应该如何确保该线程保持活动状态,以便 FileSystemWatcher 可以在文件更改时采取行动?这是在 Windows 服务器(使用 .NET 框架 2.0 版)上运行的,因此如有必要,可以将其设为 Windows 服务。

4

5 回答 5

10

如果它在服务器上运行,服务似乎是一个不错的选择。

如果你想要一些更具交互性的东西,我有一个小应用程序,它位于我的系统托盘中,当我们的问题文件夹中发生某些事情时向我显示。它使用 Application.Run() 方法来保持自身运行而不需要循环,即

class MainEntryClass
{
    static void Main(string[] args)
    {
        FolderAlerter fa = new FolderAlerter(); 
        Application.Run();
    }
}

然后我在 FolderAlerter 中设置了我的 FileSystemWatcher。

于 2009-03-18T21:37:52.457 回答
3

基本上,FileSystemWatcher 使用一些内置钩子来订阅更改,并在发生更改时让操作系统调用您的委托。所以你所要做的就是阻止你的主线程退出,它实际上不需要做任何事情;当你到达那条线时,程序的主要部分已经结束,它已经完成了它需要做的事情。

做你想做的一个简单的方法是对 MSDN 中的示例进行此更改;

//while (Console.Read() != 'q') ;
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);

这将使您的主线程永远休眠,但仍将允许委托触发并响应目录中的更改。请注意,它将继续运行多个更改(就像 MSDN 示例一样)。

请注意,MSDN 示例中的“while”实际上并没有多大作用。您可以只用“Console.Read()”替换该行,这将使任何键退出应用程序。这只是阻止主线程退出的一条线,以便在事件通知进来时它仍然存在。

但是,使用 Sleep(Timeout.Infinite) 会使您的应用程序处于用户无法轻易停止的状态,除非通过终止应用程序。如果您将其编写为控制台应用程序,为什么不坚持“按 Q 退出”?如果您决定将其编写为服务,则可能没问题,只要您处理关闭/重启事件等。

于 2009-03-18T21:52:32.327 回答
1

为此,您可能希望创建ManualResetEvent处于重置状态的 a 并在其上放置主线程WaitOne()。要终止,其他一些回调可以简单地Set()导致WaitOne()返回的事件。

于 2009-03-18T21:57:21.130 回答
0

您可以使用 Thread.Sleep 来避免空循环。但是,在系统重新启动等情况下,Windows 服务将自动重新启动。另一种方法,取决于程序/系统的其余部分是如何构建的,是使用 Windows 调度程序在单独的 .exe 文件中运行轮询逻辑。

如果您正在寻找一个健壮/弹性的解决方案,Windows 服务或基于 Windows 调度程序的方法似乎更可取。

于 2009-03-18T21:23:21.493 回答
0

Sysinternals(现在归微软所有)有 FileMon,它将为您提供所需的源代码。

从网站引用

FileMon 的核心是虚拟设备驱动程序 Filevxd.vxd。它是动态加载的,并在初始化时通过 VxD 服务 IFSMGR_InstallFileSystemApiHook 安装文件系统过滤器,以将自身插入到所有文件系统请求的调用链中。

二进制文件和来源可以在这里找到: http ://technet.microsoft.com/en-us/sysinternals/bb896642.aspx

于 2009-03-18T21:27:04.073 回答