我一直在试图理解为什么我的FSW不触发任何事件。我在Application_Start中实例化了我的以下类的新对象,并执行了WatchFile()但没有任何反应=(
public class FileWatcherClass
{
private FileSystemWatcher _watcher;
public void WatchFile(string fileName, string directory)
{
// Create a new FileSystemWatcher and set its properties.
using (_watcher = new FileSystemWatcher(directory, "*.xml"))
{
_watcher.NotifyFilter = NotifyFilters.Attributes |
NotifyFilters.CreationTime |
NotifyFilters.FileName |
NotifyFilters.LastAccess |
NotifyFilters.LastWrite |
NotifyFilters.Size |
NotifyFilters.Security;
// Add event handlers.
_watcher.Changed +=
new FileSystemEventHandler(OnChanged);
// Begin watching.
_watcher.EnableRaisingEvents = true;
}
}
// Define the event handlers.
public void OnChanged(object source, FileSystemEventArgs e) {
do something..
}
}
答案 0 :(得分:5)
问题与您使用using
语句有关:
using (_watcher = new FileSystemWatcher(directory, "*.xml"))
当执行到达using
块的末尾时,将放置观察程序,这意味着它无法再引发事件。
删除用于解决问题的方法:
_watcher = new FileSystemWatcher(directory, "*.xml");
但是,这带来了另一个问题,那就是从不部署观察者。一种方法是在IDisposable
上实现FileWatcherClass
,然后根据需要配置观察者:
public void Dispose()
{
_watcher?.Dispose(); // if _watcher isn't null, dispose it
}
然后,您只需在处理完FileWatcherClass
实例后就可以对其进行处置。
答案 1 :(得分:0)
这里的实现稍微灵活一些。
用法:
static void Main(string[] args)
{
using (var watcherManager= new FileSystemWatcherManager())
{
watcherManager.OnChangedDetected += (a) =>
{
// General event
};
watcherManager.RegisterWatcher(@"C:\temp\helloworld");
watcherManager.RegisterWatcher(@"C:\temp\api-demo", customChangeEvent: (s, e) =>
{
// Handle change directly
});
Console.ReadKey();
};
}
实施:
public sealed class FileSystemWatcherManager : IDisposable
{
private bool _disposed = false;
private readonly Dictionary<string, FileSystemWatcher> _watchers;
public delegate void ChangedDetected(FileSystemEventArgs args);
public event ChangedDetected OnChangedDetected;
public FileSystemWatcherManager()
{
_watchers = new Dictionary<string, FileSystemWatcher>();
}
~FileSystemWatcherManager()
{
Dispose(false);
}
public FileSystemWatcher RegisterWatcher(string directoryPath, string filter = "*", FileSystemEventHandler customChangeEvent = null)
{
if (Directory.Exists(directoryPath))
{
if (!_watchers.ContainsKey(directoryPath))
{
var watcher = new FileSystemWatcher(directoryPath, filter)
{
EnableRaisingEvents = true,
IncludeSubdirectories = true
};
watcher.NotifyFilter = NotifyFilters.Attributes |
NotifyFilters.CreationTime |
NotifyFilters.FileName |
NotifyFilters.LastAccess |
NotifyFilters.LastWrite |
NotifyFilters.Size |
NotifyFilters.Security;
if (customChangeEvent != null)
watcher.Changed += customChangeEvent;
else
watcher.Changed += Watcher_Changed;
_watchers.Add(directoryPath, watcher);
}
}
else
{
throw new InvalidOperationException($"Invalid Directory: {directoryPath}");
}
return _watchers.TryGetValue(directoryPath, out FileSystemWatcher value) ? value : null;
}
private void Watcher_Changed(object sender, FileSystemEventArgs e)
{
OnChangedDetected?.Invoke(e);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (_disposed)
{
if (disposing)
{
foreach(KeyValuePair<string,FileSystemWatcher> pair in _watchers)
{
pair.Value.Dispose();
}
_watchers.Clear();
}
_disposed = true;
}
}
}