Système.IO.FileSystemWatcher pour surveiller un dossier réseau-serveur-considérations de Performance

je veux regarder un arbre de dossiers sur un serveur réseau pour les changements. Les fichiers ont une extension spécifique. Il y a environ 200 dossiers dans l'arbre et environ 1200 fichiers avec l'extension que je regarde.

Je ne peux pas écrire un service à exécuter sur le serveur (off-limits! la solution doit donc être locale pour le client. L'actualité n'est pas particulièrement importante. Je peux vivre avec une minute ou plus de retard dans les notifications. Je suis de regarder pour Créer, Supprimer, Renommer et Changement.

utiliserait le système .NET.IO.fileSystemWatcher crée une grande partie d'une charge sur le serveur?

Que Diriez-vous de 10 observateurs distincts pour réduire le nombre de dossiers/fichiers observés? (jusqu'à 200 à partir de 700 dossiers, 1200 à partir de 5500 fichiers au total) plus de trafic réseau au lieu de moins? Mes pensées sont un remaniement sur le serveur pour mettre les fichiers observés sous 1 arbre. Je n'ai peut-être pas toujours cette option, d'où l'équipe d'observateurs.

je suppose que l'autre solution est une vérification périodique si le FSW crée une charge excessive sur le serveur, ou si cela ne fonctionne pas pour un tas de raisons de type SysAdmin.

Est-il une meilleure façon de le faire?

38
demandé sur Adrian Clark 2008-09-30 08:53:27

7 réponses

du point de vue de la charge du serveur, en utilisant L'IO.FileSystemWatcher pour les notifications de changement à distance dans le scénario que vous décrivez est probablement la méthode la plus efficace possible. Il utilise les FindFirstChangeNotification et ReadDirectoryChangesW fonctions API Win32 en interne, qui à leur tour communiquer avec le redirecteur réseau d'une manière optimisée (en supposant réseau Windows standard: si un redirecteur tiers est utilisé, et il ne supporte pas les fonctionnalités requises, les choses ne fonctionneront pas du tout). Le .net wrapper utilise également async I / O et tout, assurant ainsi une efficacité maximale.

Le seul problème avec cette solution est qu'elle n'est pas très fiable. Autre que d'avoir à gérer des connexions réseau qui disparaissent temporairement (ce qui n'est pas trop un problème, depuis IO.FileSystemWatcher va lancer un événement d'erreur dans ce cas que vous pouvez gérer), le mécanisme sous-jacent a certains limitations fondamentales. De la documentation MSDN pour les fonctions API Win32:

  • ReadDirectoryChangesW échoue avec ERROR_INVALID_PARAMETER lorsque la longueur du tampon est supérieure à 64 KO et que l'application surveille un répertoire sur le réseau. Ceci est dû à une limitation de la taille des paquets avec les protocoles de partage de fichiers sous-jacents

  • les Notifications ne peuvent pas être retournées lors de l'appel FindFirstChangeNotification pour un système de fichiers distant

en d'autres termes: sous haute charge (quand vous auriez besoin d'un gros buffer) ou, pire, dans des circonstances aléatoires et non spécifiées, vous pourriez ne pas recevoir les notifications que vous attendez. C'est même un problème avec les observateurs du système de fichiers local, mais c'est beaucoup plus un problème sur le réseau. une autre question ici sur SO détaille les problèmes de fiabilité inhérents avec L'API en un peu plus en détail.

lors de l'utilisation des watchers de système de fichiers, votre application devrait être en mesure de traiter ces limitations. Par exemple:

  • si les fichiers que vous recherchez ont des numéros de séquence, stockez le dernier numéro de séquence pour lequel vous avez reçu une notification, afin que vous puissiez rechercher des "lacunes" dans les notifications futures et traiter les fichiers pour lesquels vous n'avez pas reçu de notification;

  • à la réception d'un notification, toujours faire un balayage complet du répertoire. Cela peut sembler vraiment mauvais, mais puisque le scan est basé sur des événements, il est encore beaucoup plus efficace que le sondage stupide. Aussi, tant que vous gardez le nombre total de fichiers dans un seul répertoire, ainsi que le nombre de répertoires à analyser, en vertu d'un millier, l'impact de cette opération sur le rendement devrait être assez minime de toute façon.

configurer plusieurs écouteurs est quelque chose que vous devez éviter que autant que possible: si quoi que ce soit, cela rendra les choses même moins fiable...

de toute façon, si vous absolument avez pour utiliser les observateurs de système de fichiers, les choses peuvent fonctionner bien tant que vous êtes au courant des limites, et ne vous attendez pas à une notification 1:1 pour chaque fichier modifié/créé.

donc, si vous avez d'autres options (essentiellement, avoir le processus d'écriture des fichiers vous notifier dans un non-système de fichiers basé façon: n'importe quelle méthode RPC régulière sera une amélioration...), celles-ci valent certainement la peine d'être examinées du point de vue de la fiabilité.

65
répondu mdb 2017-05-23 11:53:49

j'ai utilisé les observateurs du système de fichiers de C# a plusieurs fois. La première fois que je les ai utilisés, j'ai eu des problèmes avec eux l'arrêt de travail, principalement en raison du fait que je traitais les changements dans le thread qui a rapporté le changement.

maintenant cependant, je pousse juste le changement sur une file d'attente et traite la file d'attente sur un autre fil. Cela semble résoudre le problème que j'avais à l'origine. Pour votre problème, vous pourriez avoir plusieurs observateurs poussant sur la même file d'attente.

cependant, je ne l'ai pas utilisé avec votre problème d'échelle.

9
répondu Nick Randell 2008-09-30 20:07:43

d'après mon expérience, un FSW ne crée pas un trafic réseau élevé. Cependant, s'il ya un problème de performance, votre approche de l'utilisation de plusieurs watchers et de le décomposer en moins de dossiers étant regardé semble raisonnable.

j'ai eu quelques gros problèmes avec FSW sur les disques réseau, cependant: supprimer un fichier a toujours jeté l'événement d'erreur, jamais l'événement supprimé. Je n'ai pas trouvé de solution, donc j'évite maintenant D'utiliser FSW s'il ya un moyen de contourner...

3
répondu Treb 2008-10-03 11:09:14

la documentation MSDN indique que vous pouvez utiliser le composant FileSystemWatcher pour surveiller les modifications du système de fichiers sur un réseau drive .

il indique également que le composant watcher écoute pour les notifications de changement de système de fichiers plutôt que d'interroger périodiquement le lecteur cible pour les changements.

basé sur le fait que le volume de trafic réseau dépend entièrement de ce que vous attendez le contenu de ce réseau pousse au changement. La composante FSW n'augmentera pas le niveau de trafic du réseau.

2
répondu Jim Burger 2008-09-30 05:31:16

Watcher semble 100% fiable - il suffit de regarder la taille du tampon sur l'objet watcher. J'ai testé des milliers de mises à jour, aucune perdue.

je recommande l'utilisation d'une approche multi-thread - le déclencheur étant l'observateur de fichier. Il peut lancer un thread pour chaque changement de fichier détecté. L'observateur peut traiter beaucoup plus rapidement avec moins de risques de débordement. (utiliser async thread)

1
répondu davidWazy 2014-09-24 17:13:23

après utilisation du système.IO.FileSystemWatcher pendant un moment. Il n'est pas assez stable pour gérer les événements qui arrivent trop vite. Pour s'assurer 100% lire les fichiers. J'utilise des méthodes de répertoire simples pour rechercher à travers les fichiers. Après l'avoir lu, copiez immédiatement les fichiers dans un autre dossier. Pour l'isoler des nouveaux fichiers ajoutés pendant que vous lisez les fichiers.

Timer est utilisé pour lire régulièrement le dossier. En copiant le fichier déjà lu dans le dossier d'archivage, assurez-vous que ce ne sera pas encore lire. La lecture suivante sera toujours de nouveaux fichiers.

var noms de fichiers = Répertoire.GetFiles (srcFolder); foreach (string fileName dans les noms de fichiers) { string[] lignes = Fichier.ReadAllLines (fileName);

1
répondu trevorwong77 2016-05-27 06:52:31

Je ne pense pas qu'il y ait une sorte d'état actif ou de communication entre l'ordinateur avec la FSW et l'ordinateur dont l'emplacement est surveillé. En d'autres termes, la FSW n'envoie pas le système d'exploitation en réseau pour vérifier le fichier.

on pourrait imaginer qu'un message ou un événement est seulement soulevé/envoyé à la FSW réseau lorsqu'un changement se produit.

mais ce ne sont que des spéculations. :)

-1
répondu core 2008-09-30 05:08:42