2010-02-08 3 views
8

J'essaie de créer un répertoire distant, puis d'y écrire un fichier. Chaque fois que c'est génial, l'application échoue avec une exception System.IO.DirectoryNotFoundException en essayant d'écrire le fichier. Lorsque j'écris le fichier, j'utilise l'objet DirectoryInfo retourné pour aider à créer le chemin du fichier, donc l'application semble penser que le répertoire a été créé. Cependant, le répertoire n'existe pas.Problème de latence Directory.CreateDirectory?

Est-il possible que j'essaie d'écrire dans le répertoire avant que Windows ne le crée? Je pense que Directory.CreateDirectory ne retournera pas jusqu'à ce que cette tâche soit terminée.

+0

Je n'ai pas une bonne réponse mais vous ne dites pas ce que "distant" est habituellement. Alors peut-être que c'est un cas où le serveur distant a créé le dossier sur le système de fichiers local mais ne le retourne pas encore lors de la navigation. Peut-être un problème de mise en cache (est-ce que quelque chose cache réellement la structure du système de fichiers?). –

+0

Le serveur distant est-il un serveur Windows ou un autre type de serveur exécutant Samba ou similaire? – Jacob

+0

C'est un partage IFS sur un AS400. L'application s'exécute sur une boîte Windows, en accédant au partage IFS avec un chemin UNC. – majorpayne27

Répondre

7

Réponse - Oui. Le comportement, lorsque la création de fichiers/répertoires est en retard est attendu. La solution ordinaire proposée par un autre commentateur est d'utiliser des tentatives avec un certain délai. Le comportement est le même quelles que soient les fonctions de fichier utilisées: Findfirst, CreateFile, WaitForSingleObject, etc.

Une autre solution consistera à utiliser les nouvelles fonctions transactionnelles de l'API trouvées sur les systèmes d'exploitation Vista et Windows ultérieurs.

Le problème est méchant et n'a jamais été compris par les développeurs de projets sur d'autres plates-formes et déplacés vers Windows: comme les scripts DOS/CMD, les clients SVN, Cygwin, perl, diverses applications java, divers installateurs, etc

+1

+1 Nous voyons cela tout le temps, au point où nous avons une bibliothèque complète d'appels d'E/S qui ont été réglés sur notre configuration NAS. –

+0

Est-ce que quelqu'un sait ce que sont ces autres méthodes magiques? – Mrchief

4

Bien que je n'ai jamais rencontré ce comportement et que je ne peux pas l'expliquer, une solution pragmatique consiste à configurer une boucle autour de votre appel accédant au répertoire. Attrapez DirectoryNotFoundException à l'intérieur de cette boucle, et réessayez d'y accéder plusieurs fois après une courte pause à chaque fois. Rethrow l'exception si le nombre de tentatives est dépassé. L'ajout de la consignation détaillée à ce stade peut vous aider à déterminer la cause réelle du problème.

+0

Il pourrait être plus efficace de vérifier 'Directory.Exists()' plutôt que d'intercepter l'exception à moins que cela ne retourne faussement la valeur true et que l'accès à celui-ci se déclenche. –

+0

@CoryCharlton: Comment est-ce plus efficace? La vérification du système de fichiers est pire que jeter et vérifier une exception, et probablement, le système de fichiers ferait aussi le Directory.Exists() dans ce cas de toute façon. – Arafangion

6

Je viens d'avoir ce problème et pour moi la situation était comme ça:

if(!exportDirectory.Exists) 
    exportDirectory.Create(); 

Puis plus tard, quand dans une autre classe qui a cette même objet DirectoryInfo passé à ce que je fais:

if (!exportDirectory.Exists) 
    throw new DirectoryNotFoundException(exportDirectory.FullName); 

Et le répertoire apparemment n'existe toujours pas (bien que j'ai le répertoire parent ouvert dans Windows et bien sûr je peux le voir juste en face de moi).

La solution que je trouve est après la création initiale du répertoire I devrait appeler:

exportDirectory.Refresh(); 

de Microsoft:

Actualise l'état de l'objet. (Hérité de FileSystemInfo.)

Questions connexes