-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Are static constructors thread-safe? #10243
Are static constructors thread-safe? #10243
Comments
/cc @jcouv to check this answer. My interpretation of the C# spec section on static constructors, it states:
That would seem to imply that only thread will invoke the static constructor. However, there are no restrictions on the code you write inside a static constructor. You could write code that starts new threads in the constructor. That would require your own thread synchronization. |
Yeah, this is a similar discussion #10244, there's always unsafe things you can do anywhere in code, but it's always nice to know when you don't need an extra layer of mutexing around things or not or can use the inherit constructs in the language. :) |
I'm not quite sure how you want to express this in this documentation, but C# static class constructors are thread-safe, and executed under a lock that is specific to the exact specific type of the class. (This is important for generics, i.e. the List static class constructor executes under a different lock than the List static class constructor.) Adding additional mutexes is both non-necessary, and possibly a mechanism to cause deadlock issues. The precise behavior of the thread-safety of class constructors can be found in sections 10.5.3.1 and 10.5.3.3 in partition II of the ECMA 335 standard. See http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-335.pdf Here is a short, somewhat more easily readable description of the special behavior of the class constructor lock. For exact details see section 105.3.3 as referenced above. This lock is a deadlock aware lock that will not deadlock if the class constructor for type A depends on the class constructor for type B, which in turn depends on the class constructor for type A. In that case, the class constructor lock will allow the class constructor for type B to observe the partially uninitialized state of type A, and would also allow type A to observe the partially initialized state of type B if initialization started with type B. This deadlock avoidance mechanism is robust, and works even in cases where the initialization of types A and B started on separate threads, but reasoning about the correctness of such class constructors is difficult, such that it is recommended that circular references in static constructors are to be avoided as a matter of good software engineering practice. Standard thread synchronization primitives such as monitors, semaphores, mutexes, etc, do not participate in the deadlock avoidance scheme, and it is possible to build a deadlock in their presence, if they are not used in a safe manner. |
I'll propose the following text based on the above comments:
Please vote up or down, with additional suggestions. |
As it's executed under a lock, might also be worth noting what to avoid:
|
This issue has been closed as part of the issue backlog grooming process outlined in #22351. That automated process may have closed some issues that should be addressed. If you think this is one of them, reopen it with a comment explaining why. Tag the |
Would be nice if this article could call out thread-safety aspects of static constructors. Thanks!
Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
The text was updated successfully, but these errors were encountered: