2008-09-11 6 views
17

Il existe de nombreux articles sur Internet à propos des fichiers manquants de la fonction API ReadDirectoryChangesW lorsqu'il y a beaucoup d'activité de fichier. La plupart reprochent la vitesse à laquelle la boucle de la fonction ReadDirectoryChangesW est appelée. C'est une supposition incorrecte. La meilleure explication que je l'ai vu est dans le post suivant, le commentaire le lundi 14 Avril, 2008 14:15:27Comment empêcher les modifications de fichiers manquantes dans ReadDirectoryChangesW

http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/4465cafb-f4ed-434f-89d8-c85ced6ffaa8/

Le résumé est que le fichier des rapports de fonction ReadDirectoryChangesW changements lorsqu'ils quittent la File-Write-derrière la file d'attente, pas comme ils sont ajoutés. Et si un trop grand nombre est ajouté avant d'être commis, vous perdez l'attention sur certains d'entre eux. Vous pouvez le voir avec votre implémentation, si vous écrivez simplement un programme pour générer rapidement plus de 1000 fichiers dans un répertoire. Il suffit de compter le nombre d'avis d'événements de fichiers que vous obtenez et vous verrez qu'il y a des moments où vous ne les recevrez pas tous.

La question est, quelqu'un a trouvé une méthode fiable pour utiliser la fonction ReadDirectoryChangesW sans avoir à vider le volume à chaque fois? Cela n'est pas autorisé si l'utilisateur n'est pas administrateur et peut également prendre un certain temps pour terminer.

Répondre

1

Si l'API n'est pas fiable, une solution de contournement peut être votre seule option. Bien sûr, cela implique probablement le suivi des noms et noms de fichiers modifiés. Ce que cela ne signifie pas, c'est que vous avez besoin d'interroger lors de la recherche de modifications, vous pouvez plutôt utiliser le FileSystemWatcher comme moyen de déclencher la vérification.

Donc, si vous garder une trace des 50-100 dernières fois l'événement ReadDirectoryChangesW /FSW se produisait, et vous voyez qu'il est appelé rapidement, vous pouvez détecter et déclencher la condition spéciale pour obtenir tous les fichiers qui ont été changés (et définir un drapeau pour empêcher temporairement de futurs événements faux FSW) dans quelques secondes. Comme certaines personnes sont confuses dans les commentaires sur cette solution, je vous propose de surveiller la vitesse à laquelle les événements arrivent à partir de ReadDirectoryChangesW et lorsqu'ils arrivent trop vite, essayez de tenter une solution de contournement (généralement un balayage manuel de un répertoire).

+1

Cela fonctionnerait pendant environ 99% du temps. Que se passe-t-il si un fichier dans un autre répertoire (autre que celui ayant beaucoup de modifications de fichier) est celui qui est ignoré? Vous devez scanner le répertoire pour les changements mais manquer le changement de fichier unique dans un autre. –

+0

La classe FileSystemWatcher est un moyen .NET d'envelopper ReadDirectoryChangesW, donc non, cela n'aide pas. – Garen

+0

Ma réponse était plus sur la détection du nombre d'événements dans un laps de temps pour déclencher la solution de contournement pour ReadDirectoryChangesW. – hova

0

J'ai rencontré le même problème. Mais, je n'ai pas trouvé de solution garantissant l'obtention de tous les événements. Dans plusieurs tests, je pourrais savoir que la fonction ReadDirectoryChangesW devrait être appelée à nouveau aussi vite que possible après que la fonction GetQueuedCompletionStatus soit retournée. Je suppose que si une vitesse de traitement du système de fichiers est très rapide que la vitesse de traitement de ma demande, l'application pourrait être en mesure de perdre certains événements.

Quoi qu'il en soit, j'ai séparé une logique d'analyse d'une logique de surveillance et placé une logique d'analyse sur un thread.

+0

J'ai réussi à résoudre le problème en utilisant quelque chose de similaire. Mettez en file d'attente les événements ou écrivez-les dans un fichier pour traitement ultérieur. Les écrire sur le disque était la clé pour moi. Cela peut sembler lent mais les disques sont mis en cache et les frais généraux sont inférieurs à un DB. Mon programme reflète environ 1 To par jour de modifications de fichiers - des centaines de milliers de fichiers par jour. – SilentSteel

1

Nous n'avons jamais vu ReadDirectoryChangesW être fiable à 100%. Mais, la meilleure façon de le gérer est de séparer le "reporting" du "handling".

Mon implémentation a un thread qui n'a qu'un seul travail, pour remettre tous les événements en file d'attente. Ensuite, un deuxième thread pour traiter ma file d'attente intermédiaire. En gros, vous voulez empêcher le plus possible de rendre compte des événements. En cas de CPU élevée, vous pouvez également empêcher le signalement des événements d'observateur.

+0

Puisque je n'ai pas assez de réputation pour commenter ci-dessus, je dirai que la meilleure solution est très bonne. Il vous arrive "presque là" pour 99% des cas. Ajoutez-y encore 1 chose, une ré-analyse totale périodique des dossiers que vous regardez pour rechercher des changements. – Lompican

Questions connexes