Having recently upgraded/outdated a development laptop from old faithful Windows XP (32-bit) to Windows 7 (64-bit), we came across a problem which seemed odd at first.

Some unit-tests in a customer project failed intermittently at very unexpected points – it seemed like something went quite wrong with creating and deleting directories, but it wasn’t consistent or even predictable.

Additional symptoms were UnauthorizedAccessException and IOException – The directory is not empty. Both encountered when deleting a newly created empty directory (i.e. created by the same thread which was deleting it).

Digging deeper it looked like sometimes the System.IO.Directory.Delete actually failed silently and Directory.Create succedeed but the directory wasn’t there. It seemed unlikely for this to be caused by either .NET or even the OS acting up – it would seem much more likely that there would be some problem with the unit-tests which was hidden earlier either because the old laptop with XP was slower or the like.

However, after having debugged for a while, the problem could be reproduced quite consistently by running this simple snippet (from an NUnit test):

string dir = @”C:\PROJ\OBJECT.NET\UnitTest\Server\LOGS\Week21″;

for (int i = 0; i < 5000; i++)

{

Directory.CreateDirectory(dir);

Assert.IsTrue(Directory.Exists(dir));

Directory.Delete(dir, true);

Assert.IsFalse(Directory.Exists(dir));

}

[The snippet was run in DevStudio 2008 (9.0.21022.8 RTM), with NUnit (2.5.3.9345) and TestDriven.NET Professional (2.22.2468 / 3.0.2749) using .NET 3.5 SP1 and compile-target Any CPU on Windows 7 (x64)]

Directory.Delete(dir, true) will return before the directory is actually deleted 20-30 times out of 5000 – not a lot, but more than enough to annoy. The delay from the Delete returns and until the Directory actually disappears (Exists = false) can be up to 35-40ms – again, not a lot.

This could be a problem in a lot of both development and production scenarios – not just in a unit-testing environment, where a directory is created before and deleted again after each unit-test is run.

The actual behaviour may be related to Restore Points and versioning or something else, because if the drive in the snippet is changed to a different non-system drive (without Versioning and Restore Points ?) (like a D-drive), then it succeeds – every time.

The point here being that apparently it’s unsafe to assume that Directory.Delete is blocking when running under Windows 7.


The fix in many scenarios is to just hang around after Directory.Delete and wait for Directory.Exists to return false.

However, this isn’t quite enough if a directory tree more than 1 level deep is being deleted. More about this later.