5

I was debating with a friend who states that the static constructor could give way to a race condition as the static constructor could be called multiple times. It seems this could only happen in high volume multi-threaded environments. Is that even possible?

I couldn't find any documentation to prove him wrong. Does anyone have any insight on this?

Thanks!

webber
  • 1,834
  • 5
  • 24
  • 56
  • The race condition comes if a new thread does something that would trigger the static constructor while the static constructor is already running on another thread. The thread will block until the static constructor is done running. But the static constructor might be waiting for that new thread to complete. See http://stackoverflow.com/a/8883117/385844 – phoog Apr 10 '12 at 21:41

2 Answers2

13

Is that even possible?

No. The CLR handles this for you, and prevents static constructors from being called more than once.

This is spelled out multiple times in the C# language specification. For example, section 3.1 states:

a static constructor for a type is run at most once per application domain.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 1
    This is incorrect. Eric gives an example of how here: http://stackoverflow.com/a/9792537/351385 – Tergiver Apr 10 '12 at 21:51
  • 3
    @Tergiver I was addressing the OP's statement "could give way to a race condition as the static constructor could be called multiple times" - It is always possible to create your own race condition, in any code, in any place. There are no thread safety guarantees, but the spec DOES provide a guarantee that the static constructor will only be called once, so *that specific race condition* potential does not exist. – Reed Copsey Apr 10 '12 at 21:55
  • 1
    But the question is, "Is it even possible for a cctor to be called multiple times?" The answer is, "Yes, it *is* possible." It's only possible if you initiate the call from within the cctor itself, but it is in fact possible. – Tergiver Apr 10 '12 at 21:59
  • 7
    @Tergiver: I think you two are talking past one another. In a C# program, is it possible that a race on two threads will cause one of them to run the cctor before the other? Yes. Is it possible for that race to cause a deadlock? Yes. Is it possible for two threads to race, for them to *both end up in the cctor at the same time*, and for there to then be races in the code inside the cctor? No; the lock prevents that. – Eric Lippert Apr 10 '12 at 22:21
4

The static constructor is called only once per AppDomain.
ECMA-335 states that the CLI shall guarantee that:

"A type initializer shall be executed exactly once for any given type, unless explicitly called by user code."

And i haven't heard of a convenient way to call type initializers in C#.

You could only run into problems if you create circular dependencies between Type initializers.
See here for an interesting article on that issue:
https://msmvps.com/blogs/jon_skeet/archive/2012/04/07/type-initializer-circular-dependencies.aspx)

Botz3000
  • 39,020
  • 8
  • 103
  • 127
  • You should know, that List and List are two different types. So, static constructor of List will be called twice, for example. – Aen Sidhe Apr 11 '12 at 04:37
  • 2
    @AenSidhe Because they are different types, it's not the same static constructor. Once you apply a type argument such as int or string to List, a closed type is created. The different types also each have their own set of static variables. The static constructor of the open type List will not be called. See section 4.4.2 of the [C# specification](http://download.microsoft.com/download/3/8/8/388e7205-bc10-4226-b2a8-75351c669b09/CSharp%20Language%20Specification.doc) for more info. – Botz3000 Apr 11 '12 at 06:36