Directory.CreateDirectory Latency Issue?
Asked Answered
S

3

12

I'm trying to create a remote directory, and then write a file to it. Every great once in a while, the application fails with a System.IO.DirectoryNotFoundException while trying to write the file.

When I write the file, I'm using the returned DirectoryInfo object to help create the file path, so the application seems to think that the directory has been created. However, the directory does not exist.

Is there any chance that I'm trying to write to the directory before Windows has finished creating it? I would think that the Directory.CreateDirectory would not return until this task was finished.

Sidneysidoma answered 8/2, 2010 at 23:9 Comment(4)
I don't have a good answer but you don't say what "remote" is neccesarily. So maybe it's a case where the remote server has created the folder on the local filesystem but is not returning it yet when browsing. Maybe a caching issue (would anything actually cache the filesystem structure?).Aalesund
Is the remote server a Windows server or a different type of server running Samba or similar?Lactate
It's an IFS share on an AS400. The application is running on a Windows box, accessing the IFS share with a UNC path.Sidneysidoma
Obviously an IBM bug. Catch the exception and retry it a few times.Boutwell
I
8

Answer - Yes. The behavior, when file/directory creation is lagging is expected. Ordinary solution as proposed by other commenter is to use retries with some timeout. The behavior is the same whatever file functions are used: Findfirst, CreateFile, WaitForSingleObject etc.

Another solution will be to use new transactional functions of API found on Vista and later Windows OSes.

The problem is nasty and was never understood by developers of file-intensive projects made on other platforms and moved to Windows: like DOS/CMD scripts, SVN clients, Cygwin, perl, various java applications, various installers etc.

Intolerant answered 8/2, 2010 at 23:39 Comment(1)
+1 We see this all the time, to the point we have a complete library of IO calls that have been tuned to our NAS setup.Macrobiotics
S
9

I just had this problem and for me the situation was like this:

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

Then later when in another class that has this same DirectoryInfo object passed to it I do a:

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

And the directory apparently still doesn't exist (although I have the parent directory open in windows and of course I can see it right in front of me).

The solution I found is after the initial creation of the directory I should be calling:

exportDirectory.Refresh();

From Microsoft:

Refreshes the state of the object. (Inherited from FileSystemInfo.)

Selfdrive answered 6/2, 2015 at 20:53 Comment(1)
thank you - that is very helpful; I was using Directory.CreateDirectory and getting the same latency issue. Using your example above with directoryname.refresh() did the trick 13 years later! Thank goodness for StackOverflow :-)Saki
I
8

Answer - Yes. The behavior, when file/directory creation is lagging is expected. Ordinary solution as proposed by other commenter is to use retries with some timeout. The behavior is the same whatever file functions are used: Findfirst, CreateFile, WaitForSingleObject etc.

Another solution will be to use new transactional functions of API found on Vista and later Windows OSes.

The problem is nasty and was never understood by developers of file-intensive projects made on other platforms and moved to Windows: like DOS/CMD scripts, SVN clients, Cygwin, perl, various java applications, various installers etc.

Intolerant answered 8/2, 2010 at 23:39 Comment(1)
+1 We see this all the time, to the point we have a complete library of IO calls that have been tuned to our NAS setup.Macrobiotics
L
4

While I have never experienced this behavior and cannot explain it, a pragmatic solution is to setup a loop around your call accessing the directory. Catch DirectoryNotFoundException inside that loop, and retry access a few times after a short pause each time. Rethrow the exception if the retry count is exceeded.

Adding detailed logging at this point may help you determine the actual cause of the problem.

Libertinism answered 8/2, 2010 at 23:21 Comment(2)
Might be more efficient to check Directory.Exists() rather than catching the exception unless that is falsely returning true and yet accessing it throws.Aalesund
@CoryCharlton: How is this more efficient? Checking the filesystem is an order of magnitude worse than throwing and checking an exception, and presumeably, the filesystem would also do the Directory.Exists() in that case anyway.Rickard

© 2022 - 2024 — McMap. All rights reserved.