2012-02-06 15 views
9

Tengo un FileSystemWatcher que supervisa un archivo en un recurso compartido de red. Si se produce un evento para que el recurso compartido no esté disponible, tal vez debido a un problema de red, FileSystemWatcher se desconecta.FileSystemWatcher Network Disconnect

Obviamente, puede controlar el evento "Error", tal vez hacer un poco de la tala y la gran cantidad de artículos sugieren volver a conectar el FSW dentro del controlador de eventos de error.

Pero ¿y si el recurso compartido de red aún no está disponible en el evento de error. Entonces necesito introducir un temporizador para probar si el recurso compartido de red está disponible e intentar reconectar el FSW.

1) ¿Hay un mejor enfoque?

2) ¿Hay una propiedad que me permite determinar que el FSW se ha desconectado el archivo? Noté que hay un miembro no público del FSW "stopListening", que parece establecerse en verdadero cuando el FSW se desconecta. Pero esto no es expuesto públicamente

Cualquier ayuda se agradece ...

Gracias Kevin

+0

posible duplicado de [FileSystemWatcher y desconexión de la red?] (Http://stackoverflow.com/questions/281573/filesystemwatcher-and-network-disconnect) –

+0

Gracias por la respuesta Erno, pero no, no es. Sé que puedo usar el evento Error para volver a conectar. Pero cuando se produce el evento Error, ¿qué sucede si el recurso compartido de red no está disponible? ¡A menos que tenga algún tipo de intento de temporizador/tiempo para reconectarme, no tengo otro evento para intentar reconectar! Además, FSW no expone una propiedad pública para decirme que está desconectada –

+0

De acuerdo con la publicación que sugerí, hay un evento de error que puede usar. Y el temporizador es una buena idea para buscar disponibilidad. –

Respuesta

1

Seguimiento en esto. A sugerencia de un recurso de Microsoft en los foros de MSDN, agregué esto a Microsoft Connect.

Puntos clave de la respuesta de Microsoft: - evento de error no es sólo para buffer interno desborda - Se agregará la posibilidad de exponer el propiedad stopListening a su lista de sugerencias de los clientes

Enlace aquí: http://connect.microsoft.com/VisualStudio/feedback/details/727934/filesystemwatcher-error-handling

+0

La página ya no está disponible o no hay permiso para verla: hace que la respuesta no valga la pena :( – Darren

7

un par de comentarios y sugerencias ... (que creció y creció como yo estaba escribiendo ... lo siento)

evento el FileSystemWatcher.Error se activa cuando el FileSystemWatcher consigue tantos acontecimientos que suceden tan rápidamente que no puede manejar a todos. Es no se dispara cuando ocurre un error al mirar el sistema de archivos (como la red que se está cayendo).

Creo que he tenido una situación similar. El problema es que cuando se desconecta la conexión de red, el FileSystemWatcher nunca tendrá un evento activado, porque en realidad no puede ver lo que se supone que debe estar mirando, pero no parece ser consciente del hecho. Cuando vuelve la conexión de red, FileSystemWatcher no se recupera, es decir, todavía no puede ver la conexión (restaurada). La única solución que se nos ocurrió que parecía funcionar de manera confiable era tener un temporizador que soltaba regularmente todo el objeto FileSystemWatcher y creaba uno nuevo, configuraba todos los eventos y miraba la carpeta, etc. Ya que descartar y crear un nuevo FileSystemWatcher es (relativamente) rápido (es decir, milisegundos), puede configurar el temporizador para que se active cada 10 segundos o más sin consumir demasiado del procesador. Por supuesto, si la red aún está fuera, FileSystemWatcher no podrá ver la red sin importar lo que haga. Pero está bien, volverá a intentarlo en otros 10 segundos.

Dos cosas a tener en cuenta con esta solución:

  1. Cuando el temporizador se activa, se tiene que comprobar que el FileSystemWatcher no está procesando actualmente ningún evento, y tiene que esperar si lo es. Por lo tanto, en el evento de temporizador, detenga el temporizador, evite que FileSystemWatcher genere eventos, luego espere a que finalice cualquier evento de FileSystemWatcher (usando lock (...) {...} es una buena forma de hacerlo).
  2. Después de caer y volver a crear la FileSystemWatcher, es necesario comprobar manualmente para cualquier evento que pudiera haber ocurrido mientras que el FileSystemWatcher estaba siendo refrescado (o mientras que la red estaba abajo). Por ejemplo, si está viendo archivos que se crean y se crea un archivo mientras actualiza FileSystemWatcher o mientras la conexión de red no está disponible, no obtendrá eventos para esos archivos cuando inicie la nueva instancia de FileSystemWatcher (ya que los archivos ya han sido creados).

Yo espero que ayude.

+0

Gracias por la respuesta Mark. Después de volver a leer el documento de MSDN, veo que está en lo cierto, el evento de error no se dispara cuando se produce un error al mirar el sistema de archivos, lo cual fue un malentendido de mi parte. –

+1

Su enfoque es interesante, sin embargo (probablemente debido a un defecto de diseño), el FileSystemWatcher es en realidad una estática dentro de un servicio WCF de alto volumen. Entonces, el concepto de tener que reiniciarlo cada 10 segundos probablemente no sea una opción para nosotros, incluso un pequeño golpe de rendimiento podría ser costoso para nuestros tiempos de respuesta requeridos. Parece que no hay respuesta, ya que no podemos confiar absolutamente en el evento de error, la solución óptima sería volver a factorizar nuestra solución para eliminar el FileSystemWatcher, ya que parece ser un enfoque poco confiable. –

0

¿No funcionaría algo así? Parece que funciona para mi caso de prueba simple.

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 
    } 
});