Disconnessione di rete FileSystemWatcher

Ho un FileSystemWatcher che monitora un file su una condivisione di rete. Se si verifica un evento per rendere la condivisione non disponibile, forse a causa di un problema di rete, FileSystemWatcher si disconnette.

Ovviamente posso gestire l’evento “Errore”, magari fare un po ‘di logging e molti articoli suggeriscono di ricolbind l’FSW all’interno del gestore di eventi di errore.

Ma cosa succede se la condivisione di rete non è ancora disponibile all’interno dell’evento di errore. Devo quindi introdurre un timer per verificare se la condivisione di rete è disponibile e tentare di ricolbind l’FSW.

1) Esiste un approccio migliore?

2) Esiste una proprietà che mi consente di stabilire che il file VW è stato disconnesso dal file? Noto che c’è un membro non pubblico di “stopListening” della FSW, che sembra essere impostato su true quando l’FSW viene disconnesso. Ma questo non è esposto pubblicamente

Qualsiasi aiuto sarebbe apprezzato …

Grazie Kevin

Un paio di commenti e suggerimenti … (che crebbe e crebbe mentre stavo scrivendo … scusa)

L’evento FileSystemWatcher.Error viene generato quando FileSystemWatcher ottiene così tanti eventi che accadono così rapidamente da non poterli gestire tutti. Non viene generato quando si verifica un errore durante la visualizzazione del file system (ad esempio la caduta della rete).

Credo di aver avuto una situazione simile. Il problema è che quando la connessione di rete si interrompe, FileSystemWatcher non avrà mai triggersto un evento, perché in realtà non è in grado di vedere ciò che si suppone stia guardando, ma non sembra essere a conoscenza del fatto. Quando la connessione di rete ritorna, FileSystemWatcher non si ripristina, ovvero non riesce ancora a vedere la connessione (ripristinata). L’unica soluzione che ci è sembrata funzionare in modo affidabile era quella di avere un timer che cadesse regolarmente l’intero object FileSystemWatcher e ne creasse uno nuovo, impostando tutti gli eventi e la cartella di controllo ecc. Da quando è caduto e creato un nuovo FileSystemWatcher è ( relativamente) veloce (ovvero millisecondi) è ansible impostare il timer per l’triggerszione ogni 10 secondi circa senza utilizzare troppo il processore. Naturalmente, se la rete è ancora fuori, FileSystemWatcher non sarà in grado di vedere la rete, indipendentemente da ciò che fai. Ma va bene, ci riproverà tra altri 10 secondi.

Due cose a cui fare attenzione con questa soluzione:

  1. Quando il timer si triggers, è necessario verificare che FileSystemWatcher non stia elaborando alcun evento e che debba attendere se lo è. Quindi, nell’evento timer, interrompi il timer, interrompi FileSystemWatcher dagli eventi, quindi attendi che tutti gli eventi FileSystemWatcher finiscano (utilizzando il blocco (…) {…} è un buon modo per farlo).
  2. Dopo aver rilasciato e ricreato FileSystemWatcher, è necessario verificare manualmente eventuali eventi che potrebbero essersi verificati durante l’aggiornamento di FileSystemWatcher (o mentre la rete era intriggers). Ad esempio, se stai guardando i file che vengono creati e un file viene creato durante l’aggiornamento di FileSystemWatcher o mentre la connessione di rete è fuori, non otterrai eventi per quei file quando avvii la nuova istanza di FileSystemWatcher ( poiché i file sono già stati creati).

Spero che aiuti.

Follow-up in questo. Su suggerimento di una risorsa Microsoft sui forum MSDN, l’ho aggiunto a Microsoft Connect.

Punti chiave del feedback di Microsoft: – L’evento di errore non è solo per overflow del buffer interno – Aggiungerà la possibilità di esporre la proprietà stopListening al proprio elenco di suggerimenti dei clienti

Link qui: http://connect.microsoft.com/VisualStudio/feedback/details/727934/filesystemwatcher-error-handling

Non sarebbe qualcosa di simile a questo lavoro? Sembra funzionare per il mio semplice caso di test.

var fsw = new FileSystemWatcher("[folder]", "*.*") { IncludeSubdirectories = true}; var fsw_processing = false; fsw.Deleted += (s, e) => { fsw_processing = true; fsw.EnableRaisingEvents = false; //...... fsw.EnableRaisingEvents = true; fsw_processing = false; }; fsw.Changed += (s, e) => { fsw_processing = true; fsw.EnableRaisingEvents = false; //...... fsw.EnableRaisingEvents = true; fsw_processing = false; }; //governor thread to check FileSystemWatcher is still connected. //It seems to disconnects on network outages etc. Task.Run(() => { while (true) { if (fsw.EnableRaisingEvents == false && fsw_processing == false) { try {fsw.EnableRaisingEvents = true;} catch (Exception) { fsw.EnableRaisingEvents = false; } } System.Threading.Thread.Sleep(1000 * 10);//sleep 10 secs } });