2012-02-02 11 views
8

Estoy usando un FileSystemWatcher (en una aplicación web ASP.NET) para monitorear un archivo de cambios. El observador está configurado en el constructor de una clase Singleton, por ejemplo:¿Debo guardar una referencia a FileSystemWatcher?

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... 
} 

Todo funciona bien hasta el momento. Pero mi pregunta es:

¿Es seguro configurar al vigilante usando una variable local (var fsw)? ¿O debería mantener una referencia en un campo privado para evitar que se recolecte basura?

Respuesta

6

En el ejemplo anterior FileSystemWatcher se mantiene activo solo porque la propiedad EnableRaisingEvents está configurada en true. El hecho de que la clase Singleton tenga un controlador de eventos registrado en el evento FileSystemWatcher.Changed no tiene ninguna incidencia directa en fsw siendo elegible para la recolección de basura. Ver Do event handlers stop garbage collection from occurring? para más información.

El siguiente código muestra que con EnableRaisingEvents conjunto de false, el objeto FileSystemWatcher es basura recogida: Una vez GC.Collect() se llama, la propiedad IsAlive en el WeakReference es 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); 
    } 
} 
+0

No encuentro documentación que indique que 'EnableRaisingEvents' tenga algún efecto en la recolección de basura. Pensé que se necesitaba un campo local para garantizar que 'FileSystemWatcher' no fuera basura. – Lukazoid

+0

He editado mi respuesta con un ejemplo que muestra que FileSystemWatcher es basura si EnableRaisingEvents es falso. –

+0

Gracias por eso, desearía que la funcionalidad estuviera documentada en MSDN, parece que sería demasiado fácil terminar con algunos 'FileSystemWatcher' colgantes. – Lukazoid

Cuestiones relacionadas