Is CreateDirectory() in C# thread-safe?
Asked Answered
C

3

16

Can I safely attempt to create the same directory from two different threads, without having one of them throw an exception, or run into other issues?

Note that according to MSDN, it is OK to call CreateDirectory() on a directory which already exists, in which case the method is expected to do nothing.

Christeenchristel answered 5/3, 2012 at 19:33 Comment(0)
I
18

The Directory.CreateDirectory call itself is safe to make from multiple threads. It will not corrupt program or file system state if you do so.

However it's not possible to call Directory.CreateDirectory in such a way to guarantee it won't throw an exception. The file system is an unpredictable beast which can be changed by other programs outside your control at any given time. It's very possible for example to see the following occur

  • Program 1 Thread 1: Call CreateDirectory for c:\temp\foo and it succeeds
  • Program 2 Thread 1: Removes access to c:\temp from program 1 user
  • Program 1 Thread 2: Call CreateDirectory and throws due to insufficient access

In short you must assume that Directory.CreateDirectory, or really any function which touches the file system, can and will throw and handle accordingly.

Isar answered 5/3, 2012 at 19:36 Comment(0)
L
6

From the MSDN docs on Directory:

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Therefore, as CreateDirectory is static, yes, it is thread safe.

That said: as @JaredPar points out, thread safety issues are not the only reason that a method can throw exceptions. There are a multitude of reasons why a filesystem call might throw an exception (under any circumstances, multithreaded or not), and you need to account for those.

By saying it is thread safe I (and MSDN) only imply the very literal interpretation of that, meaning "this method does not modify shared program state in a way that could cause invalid state, race conditions, or other adverse effects commonly associated with unsafe multithreaded code"

Lorielorien answered 5/3, 2012 at 19:36 Comment(2)
This doesn't address the issue though of whether or not it will throw from one or both threadsIsar
True- I believe your answer covers that better (I upvoted btw). I'll amend my answer.Lorielorien
T
4

To elaborate on @JaredPar's answer, you have a race condition on your hands. If the first call creates the folder completely, and only then the second call starts, everything will be OK.

however, if the second call reaches the OS while it is still processing the first, the OS might fail the second one dune to locking issues, and you will get an exception.

It is still thread safe in the sense that you won't get any unpredictable folders created, or no folder at all.

To elaborate - while I'm not 100% sure that Windows doesn't have an internal race condition when the same folder is created twice concurrently, I'm pretty certain you won't be able to trash the disk by doing that, or get a deadlock with both creations being stuck to death. One of them will succeed, the other will fail, but the folder will be created.

So your heuristics, just to be absolutely sure, should be this:

  • Create Directory
  • If it fails, wait a random amount of time (say, between 0.2 and 0.5 of a second) and try again.
  • If it fails constantly (say, 3 times in a row), you have another problem at your hands - no permissions to the folder, a full disk, etc..

    Incidentally, why not create the folder once when the application starts running?

Tankage answered 5/3, 2012 at 19:53 Comment(2)
are you sure about this? My intention was to have several different threads create (separate) log files in the same directory, creating it if needed. Assuming you are correct, and folder creation is not an atomic operation, I must use (e.g.) a lock to synchronize it. What's "thread-safe" about CreateDirectory() then?Christeenchristel
Thanks. I think this might be the behavior I'm seeing.Yan

© 2022 - 2024 — McMap. All rights reserved.