Directory c:\test has 50 or so files in it, no subdirectories.
If IO.Directory.Exists("C:\test") Then
IO.Directory.Delete("C:\test", True)
End If
IO.Directory.CreateDirectory("C:\test")
Drive C is Intel's X25-M80 SSD drive, OS is Windows 7 64 bit with TRIM support, Visual Studio is 2008 with target framework 3.5. When above code is executed, CreateDirectory breaks code execution without an (visible) exception. After much headache I found that Delete is not yet done by the time code execution gets to CreateDirectory. If I modify my code like this:
If IO.Directory.Exists("C:\test") Then
IO.Directory.Delete("C:\test", True)
End If
Threading.Thread.Sleep(2000)
IO.Directory.CreateDirectory("C:\test")
then everything works as expected.
My questions beside the obvious WTF here are:
- shouldn't IO.Directory.Delete be a blocking function call no matter what the drive is
- is SSD "cheating" on delete due to enabled TRIM support?
I had the same problem. I ended up deleting only the contents of the directory
@"C:\test"
and copying the new files to the directory. That was my problem:Using Directory.Delete() and Directory.CreateDirectory() to overwrite a folder
I suspect that you've found a race condition in NTFS that was previously not exposed since drives didn't exist that were fast enough to hit it. I don't think that TRIM has anything to do with it (though I reserve the right to be wrong!)
Either way, the proper way to handle this is to put the code in a Retry loop:
Yes, it has nothing to do with SSD drive. I had same problem but only on a client laptop. I am using .NET 3.5. In my case, the directory had a single file. CreateDirectory seems to be executing first internally before Delete is finished.
This was a code that worked well for three years on many computers. Client changed to a new laptop and the code consistently fails for him. I can not reproduce the scenario on development/test machines with same configuration.
After exploring System.IO.Directory with reflector, it looks like .Delete is just a wrapper around the FindFirstFile, FindNextFile, and RemoveDirectory Win API calls. There's nothing threaded or asynchronous about the .Net runtime's invokation of those API calls, or the API implementation themselves.
Now, supposing its somehow a TRIM issue, you can disable TRIM by opening an elevated command prompt and using fsutil:
To enable, run the same command with 0 as parameter.
To query, use query as the command argument:
I've had problems with this before, but this is not specific to SSD drives. You would be far better off doing a move then delete:
The other way to deal with it is to loop until complete:
If that's really the application code, note that you are really trying to delete the directory named "est"!
Escape your path to be "c:\test" or use the @ operator @"c:\test".