Нужно ли хранить ссылку на FileSystemWatcher? - PullRequest
9 голосов
/ 02 февраля 2012

Я использую 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)? Или я должен хранить ссылку на него в приватном поле, чтобы предотвратить его сборку мусора?

1 Ответ

9 голосов
/ 03 февраля 2012

В приведенном выше примере FileSystemWatcher сохраняется только потому, что для свойства EnableRaisingEvents установлено значение true. Тот факт, что класс Singleton имеет обработчик события, зарегистрированный для события FileSystemWatcher.Changed, не имеет прямого отношения к тому, что fsw имеет право на сборку мусора. См. Остановлены ли обработчики событий для сбора мусора? для получения дополнительной информации.

Следующий код показывает, что с 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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...