我有以下代码用于监视文本文件的目录,该目录每天两次获取新文件,代码工作正常但在此之后它停止触发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);
}
无法弄清楚问题。
此外,我想知道一个简单的替代方案(如果有的话),因为我没有找到这个可靠的..
答案 0 :(得分:7)
因为Run
方法完成后,watcher
才有资格进行垃圾回收。
这意味着一段时间后watcher
将被收集,显然将停止提升事件。
要解决此问题,请在外部范围内保留观察者的参考:
private static FileSystemWatcher watcher;
public static void Run()
{
watcher = new FileSystemWatcher();
...
}
答案 1 :(得分:4)
问题在于GC正在收集对FILESYSTEMWATCHER的引用,因此在一段时间之后,FILEWATCHER有一个空引用,导致事件没有被提升。
解决方案: -
private static FileSystemWatcher watcher;
public static void Run()
{
watcher = new FileSystemWatcher();
...
GC.KeepAlive(watcher);
}
只是按照建议在外部范围内保留观察者的参考并没有解决问题。我已经明确指定GC不应该收集FileWatcher对象。
答案 2 :(得分:0)
假设您的观察者不在范围之外,您可以检查发生的任何错误,例如用完监视器内部缓冲区......
watcher.Error += Watcher_Error;
...
private void Watcher_Error(object sender, ErrorEventArgs e)
{
Debug.WriteLine("Watcher_Error: " + e.GetException().Message);
}