2012-02-02 22 views
8

Używam FileSystemWatcher (w aplikacji sieci web ASP.NET) do monitorowania pliku zmian. Obserwator jest skonfigurowany w konstruktorze klasy Singleton, np .:Czy muszę zachować odniesienie do 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... 
} 

Wszystko do tej pory działa dobrze. Ale moje pytanie brzmi:

Czy bezpiecznie jest skonfigurować obserwatora za pomocą zmiennej lokalnej (var fsw)? Czy powinienem zachować odniesienie do niego w prywatnym polu, aby zapobiec gromadzeniu śmieci?

Odpowiedz

6

W powyższym przykładzie FileSystemWatcher jest utrzymywany przy życiu tylko dlatego, że właściwość EnableRaisingEvents jest ustawiona na true. Fakt, że klasa Singleton ma program obsługi zdarzeń zarejestrowany dla zdarzenia FileSystemWatcher.Changed, nie ma żadnego bezpośredniego wpływu na fsw, które kwalifikuje się do usuwania śmieci. Aby uzyskać więcej informacji, patrz Do event handlers stop garbage collection from occurring?.

Poniższy kod pokazuje, że z EnableRaisingEvents zestaw do false, obiekt FileSystemWatcher to śmieci gromadzone: Raz GC.Collect() nazywa właściwość IsAlive na WeakReference jest 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

Nie mogę znaleźć żadnej dokumentacji, aby powiedzieć, że 'EnableRaisingEvents' ma jakikolwiek wpływ na odśmiecanie. Myślałem, że lokalne pole jest potrzebne do zapewnienia, że ​​'FileSystemWatcher' nie jest zbiorem śmieci. – Lukazoid

+0

Edytowałem swoją odpowiedź na przykładzie, który pokazuje, że FileSystemWatcher jest zbędny, jeśli EnableRaisingEvents jest fałszywe. –

+0

Dziękuję za to, chciałbym, aby ta funkcjonalność została udokumentowana w MSDN, wygląda na to, że zbyt łatwo byłoby skończyć z jakimś wiszącym 'FileSystemWatcher's. – Lukazoid