FileSystemWatcher在一段时间后不会触发

Raj*_*eja 2 .net c# filesystemwatcher c#-4.0

我有以下代码用于监视文本文件的目录,该目录每天两次获取新文件,代码工作正常,但之后它停止触发OnCreated事件...

[PermissionSet(SecurityAction.Demand, Name="FullTrust")]
public static void Run()
{
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = @"c:\users\documents\";

    watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
       | NotifyFilters.FileName | NotifyFilters.DirectoryName;

    watcher.Filter = "*.txt";

    // Add event handlers.
    watcher.Created += new FileSystemEventHandler(OnCreated);

    // Begin watching.
    watcher.EnableRaisingEvents = true;

    // Wait for the user to quit the program.
    Console.WriteLine("Press \'q\' to quit the sample.");
    while(Console.Read()!='q');
}

private static void OnCreated(object source, FileSystemEventArgs e)
{
   Console.WriteLine("File: " +  e.FullPath + " " + e.ChangeType);
}
Run Code Online (Sandbox Code Playgroud)

无法弄清楚这个问题.

此外,我想知道一个简单的替代品(如果有的话),因为我没有找到这个可靠..

Alb*_*rto 7

因为Run方法完成后,watcher才有资格进行垃圾回收.这意味着一段时间后watcher会被收集,显然会停止提升事件.

要解决,请在外部范围内保留观察者的参考:

private static FileSystemWatcher watcher;

public static void Run()
{
    watcher = new FileSystemWatcher();
    ...
}
Run Code Online (Sandbox Code Playgroud)

  • @Steve:引用的生命周期不一定由变量的范围扩展,只能通过引用是否"活动"来扩展.由于在`watcher.EnableRaisingEvents = true之后不再使用`watcher`局部变量;`GC可能认为它处于非活动状态并可能会收集它. (3认同)

Raj*_*eja 5

问题在于,GC 正在收集对 FILESYSTEMWATCHER 的引用,因此一段时间后 FILEWATCHER 有一个空引用,导致事件未引发。

解决方案 :-

private static FileSystemWatcher watcher;
public static void Run()
{
watcher = new FileSystemWatcher();
...
GC.KeepAlive(watcher);  
}
Run Code Online (Sandbox Code Playgroud)

只是按照建议在外部范围内保留观察者的参考并不能解决问题。我已经明确指定 GC 不应收集 FileWatcher 对象。