System.IO.FileSystemWatcher para supervisar una carpeta de servidor de red – Consideraciones de rendimiento

Quiero ver un árbol de carpetas en un servidor de red para cambios. Todos los archivos tienen una extensión específica. Hay alrededor de 200 carpetas en el árbol y aproximadamente 1200 archivos con la extensión que estoy viendo.

No puedo escribir un servicio para ejecutar en el servidor (¡fuera de límites!) Por lo que la solución debe ser local para el cliente. La puntualidad no es particularmente importante. Puedo vivir con un minuto o más de retraso en las notificaciones. Estoy mirando para Crear, Eliminar, Renombrar y Cambios.

¿Usaría .NET System.IO.fileSystemWatcher para crear mucha carga en el servidor?

¿Qué hay de 10 vigilantes por separado para reducir el número de carpetas / archivos que se ven? (hasta 200 de 700 carpetas, 1200 de 5500 archivos en total) ¿Más tráfico de red en lugar de menos? Mis pensamientos son una reorganización en el servidor para poner los archivos vistos bajo 1 árbol. Puede que no siempre tenga esta opción, por lo tanto, el equipo de observadores.

Supongo que la otra solución es una comprobación periódica si el FSW crea una carga indebida en el servidor, o si no funciona para un montón de razones de tipo SysAdmin.

¿Hay una mejor manera de hacer esto?

Desde el punto de vista de la carga del servidor, el uso de IO.FileSystemWatcher para las notificaciones de cambio remoto en el escenario que usted describe probablemente sea el método más eficiente posible. Utiliza las funciones FindFirstChangeNotification y ReadDirectoryChangesW Win32 API internamente, que a su vez se comunican con el redirector de red de forma optimizada (asumiendo que las redes de Windows son estándar: si se usa un redirector de terceros y no admite la funcionalidad requerida, las cosas ganaron no funciona en absoluto). .NET wrapper también usa asincronización de E / S y todo, asegurando aún más eficacia.

El único problema con esta solución es que no es muy confiable. Aparte de tener que lidiar con conexiones de red que se van temporalmente (lo cual no es un problema, ya que IO.FileSystemWatcher desencadenará un evento de error en este caso que puede manejar), el mecanismo subyacente tiene ciertas limitaciones fundamentales. De la documentación de MSDN para las funciones de API de Win32:

  • ReadDirectoryChangesW falla con ERROR_INVALID_PARAMETER cuando la longitud del búfer es superior a 64 KB y la aplicación está supervisando un directorio en la red. Esto se debe a una limitación de tamaño de paquete con los protocolos subyacentes de uso compartido de archivos

  • Es posible que las notificaciones no se devuelvan al llamar a FindFirstChangeNotification para un sistema de archivos remoto

En otras palabras: bajo alta carga (cuando necesitaría un gran buffer) o, peor aún, en circunstancias no especificadas al azar, es posible que no reciba las notificaciones que espera. Esto es incluso un problema con los observadores locales del sistema de archivos, pero es un problema mucho más grave en la red. Otra pregunta aquí en SO detalla los problemas de confiabilidad inherentes con la API con un poco más de detalle.

Al usar vigilantes del sistema de archivos, su aplicación debería poder lidiar con estas limitaciones. Por ejemplo:

  • Si los archivos que está buscando tienen números de secuencia, almacene el último número de secuencia del que recibió la notificación, para que pueda buscar “lagunas” en las notificaciones futuras y procesar los archivos para los que no recibió notificaciones;

  • Al recibir una notificación, siempre realice un escaneo completo del directorio. Esto puede sonar muy mal, pero dado que el escaneo depende de los eventos, sigue siendo mucho más eficiente que un sondeo tonto. Además, siempre y cuando mantenga la cantidad total de archivos en un solo directorio, así como la cantidad de directorios para escanear, menos de mil, el impacto de esta operación en el rendimiento debería ser mínimo.

Configurar múltiples oyentes es algo que debes evitar tanto como sea posible: en todo caso, esto hará que las cosas sean aún menos confiables …

De todos modos, si tienes que usar vigilantes del sistema de archivos, las cosas pueden funcionar bien siempre que conozcas las limitaciones y no esperes una notificación 1: 1 para cada archivo modificado / creado.

Entonces, si tiene otras opciones (esencialmente, hacer que el proceso de escritura de los archivos le notifique de una manera que no esté basada en un sistema de archivos: cualquier método RPC regular será una mejora …), definitivamente vale la pena investigar desde un punto de confiabilidad de vista.

He usado los vigilantes del sistema de archivos de C # varias veces. La primera vez que los usé, tuve problemas para dejar de trabajar, principalmente debido a que estaba procesando los cambios en el hilo que informaron el cambio.

Ahora, sin embargo, simplemente coloco el cambio en una cola y proceso la cola en otro hilo. Esto parece resolver el problema que originalmente tuve. Para su problema, podría hacer que varios observadores presionen la misma cola.

Sin embargo, no he usado esto con su tipo de escala de problema.

En mi experiencia, un FSW no crea un alto tráfico de red. Sin embargo, si hay un problema de rendimiento, su enfoque de usar varios observadores y descomponerlo en menos carpetas que se estén viendo suena razonable.

Sin embargo, tuve algunos problemas importantes con FSW en las unidades de red: al eliminar un archivo siempre se lanzaba el evento de error, nunca el evento eliminado. No encontré una solución, así que ahora evito usar FSW si hay una forma de evitarlo …

La documentación de MSDN indica que puede usar el componente FileSystemWatcher para observar los cambios en el sistema de archivos en una unidad de red.

También indica que el componente del vigilante escucha las notificaciones de cambio del sistema de archivos en lugar de interrogar periódicamente a la unidad de destino por cambios.

En función de eso, la cantidad de tráfico de red depende completamente de cuánto esperas que cambie el contenido de esa unidad de red. El componente FSW no se agregará al nivel de tráfico de red.

Watcher parece 100% confiable, solo observa el tamaño del búfer en el objeto del observador. He probado miles de actualizaciones de archivos, ninguna perdida.

Recomiendo usar un enfoque de múltiples subprocesos: el desencadenante es el observador de archivos. Puede iniciar un hilo por cada cambio de archivo detectado. El observador puede procesar mucho más rápido con menos posibilidades de desbordamiento. (use hilo Async)

Después de usar System.IO.FileSystemWatcher por algún tiempo. No es lo suficientemente estable como para manejar eventos que llegan demasiado rápido. Para garantizar el 100% de lectura de los archivos. Utilizo métodos de directorio simples para buscar a través de los archivos. Después de leerlo, copie de inmediato los archivos a otra carpeta. Para aislarlo de los nuevos archivos que se agregan mientras lee los archivos.

Timer se usa para leer regularmente la carpeta. Al copiar el archivo ya leído en la carpeta de archivo, asegúrese de que no vuelva a leerse. La lectura posterior será siempre archivos nuevos.

var fileNames = Directory.GetFiles (srcFolder); foreach (string FileName en fileNames) {string [] lines = File.ReadAllLines (fileName);

No creo que haya ningún tipo de estado activo o comunicación entre la computadora con el FSW y la computadora cuya ubicación está siendo monitoreada. En otras palabras, el FSW no está haciendo ping al sistema operativo en red para verificar el archivo.

Uno imaginaría que un mensaje o evento solo se genera / envía a la FSW en red cuando ocurre un cambio.

Pero esto es solo una especulación. 🙂