2012-02-02 12 views
8

Sto utilizzando uno FileSystemWatcher (in un'applicazione Web ASP.NET) per monitorare un file per le modifiche. L'osservatore è impostato nel costruttore di una classe Singleton, ad esempioDevo mantenere un riferimento 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... 
} 

Tutto funziona bene finora. Ma la mia domanda è:

È sicuro impostare l'osservatore utilizzando una variabile locale (var fsw)? O dovrei mantenere un riferimento ad esso in un campo privato per evitare che venga raccolto dalla spazzatura?

risposta

6

Nell'esempio sopra FileSystemWatcher viene mantenuto attivo solo perché la proprietà EnableRaisingEvents è impostata su true. Il fatto che la classe Singleton abbia un gestore eventi registrato sull'evento FileSystemWatcher.Changed non ha alcun effetto diretto su fsw che è idoneo per la Garbage Collection. Vedere Do event handlers stop garbage collection from occurring? per ulteriori informazioni.

Il codice seguente mostra che con EnableRaisingEvents insieme al false, l'oggetto è FileSystemWatcher garbage collection: Una volta GC.Collect() è chiamato, la proprietà IsAlive sul 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); 
    } 
} 
+0

Non riesco a trovare alcuna documentazione per dire che 'EnableRaisingEvents' ha alcun effetto sulla garbage collection. Ho pensato che fosse necessario un campo locale per garantire che 'FileSystemWatcher' non fosse un garbage collector. – Lukazoid

+0

Ho modificato la mia risposta con un esempio che mostra FileSystemWatcher è garbage collection se EnableRaisingEvents è false. –

+0

Grazie per questo, vorrei che la funzionalità fosse documentata su MSDN, sembra che sarebbe troppo facile finire con alcuni 'FileSystemWatcher' in sospensione. – Lukazoid

Problemi correlati