【问题标题】:Do I need to keep a reference to a FileSystemWatcher?我需要保留对 FileSystemWatcher 的引用吗?
【发布时间】:2012-02-02 10:21:36
【问题描述】:

我正在使用FileSystemWatcher(在 ASP.NET Web 应用程序中)来监视文件的更改。观察者在 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) 设置观察程序是否安全?或者我应该在私有字段中保留对它的引用以防止它被垃圾收集?

【问题讨论】:

    标签: c# asp.net garbage-collection filesystemwatcher


    【解决方案1】:

    在上面的示例中,FileSystemWatcher 保持活动状态只是因为属性 EnableRaisingEvents 设置为 true。 Singleton 类具有注册到FileSystemWatcher.Changed 事件的事件处理程序这一事实与fsw 有资格进行垃圾收集没有任何直接关系。请参阅Do event handlers stop garbage collection from occurring? 了解更多信息。

    以下代码显示,当EnableRaisingEvents 设置为false 时,FileSystemWatcher 对象被垃圾回收:一旦调用GC.Collect()WeakReference 上的IsAlive 属性为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);
        }
    }
    

    【讨论】:

    • 我找不到说明EnableRaisingEvents 对垃圾回收有任何影响的文档。我认为需要一个本地字段来确保 FileSystemWatcher 不会被垃圾收集。
    • 我已经用一个示例编辑了我的答案,该示例显示如果 EnableRaisingEvents 为 false,FileSystemWatcher 将被垃圾收集。
    • 谢谢您,我希望 MSDN 上记录了该功能,看起来很容易以挂起FileSystemWatchers 告终。
    • 感谢 Muath 的精彩回答。但是,您能否解释一下为什么当“EnableRaisingEvents 设置为 true”时,GC 不收集对象?
    猜你喜欢
    • 1970-01-01
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 2013-09-14
    • 2015-11-13
    • 1970-01-01
    相关资源
    最近更新 更多