我正在使用FileSystemWatcher
(在ASP.NET网络应用中)来监控文件的更改。观察者在Singleton类的构造函数中设置,例如:
private SingletonConstructor()
{
var fileToWatch = "{absolute path to file}";
var fsw = new FileSystemWatcher(
Path.GetDirectoryName(fileToWatch),
Path.GetFileName(fileToWatch));
fsw.Changed += OnFileChanged;
fsw.EnableRaisingEvents = true;
}
private void OnFileChanged(object sender, FileSystemEventArgs e)
{
// process file...
}
到目前为止一切正常。但我的问题是:
使用局部变量(var fsw
)设置观察者是否安全?或者我应该在私有字段中保留它的引用,以防止它被垃圾收集?
答案 0 :(得分:9)
在上面的示例中,FileSystemWatcher
仅保留,因为属性EnableRaisingEvents
设置为true
。 Singleton类具有注册到FileSystemWatcher.Changed
事件的事件处理程序的事实与fsw
有资格进行垃圾收集没有任何直接关系。有关详细信息,请参阅Do event handlers stop garbage collection from occurring?。
以下代码显示,EnableRaisingEvents
设置为false
时,FileSystemWatcher
对象被垃圾回收:调用GC.Collect()
后,IsAlive
属性WeakReference
为false
。
class MyClass
{
public WeakReference FileSystemWatcherWeakReference;
public MyClass()
{
var fileToWatch = @"d:\temp\test.txt";
var fsw = new FileSystemWatcher(
Path.GetDirectoryName(fileToWatch),
Path.GetFileName(fileToWatch));
fsw.Changed += OnFileChanged;
fsw.EnableRaisingEvents = false;
FileSystemWatcherWeakReference = new WeakReference(fsw);
}
private void OnFileChanged(object sender, FileSystemEventArgs e)
{
// process file...
}
}
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
GC.Collect();
Console.WriteLine(mc.FileSystemWatcherWeakReference.IsAlive);
}
}