Potential pitfalls with static constructors in C# - c#

My question comes after refactoring a class that contained only static methods to be declared as a static class, and experiencing weird issues when starting the application.
I have not performed any thorough investigation but it seems that some call being made from within the static constructor does not complete for some reason.
So, I would like to know where there are any pitfalls when using static constructors in C#? More specifically, are there any things that should be avoided at all cost and not be used from within the static constructor?

There are several pitfalls to static constructors. For example, if a static constructor throws an exception, you would continue getting a TypeInitializationException whenever you access any of its members.
If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.
In general, static classes should only be used in stateless scenarios where you won’t need any initialization. If your class needs to be initialized, you might be better off using the singleton pattern, which can be lazily initialized on first access:
public class MyClass
{
private static readonly Lazy<MyClass> current =
new Lazy<MyClass>(() => new MyClass());
public static MyClass Current
{
get { return current.Value; }
}
private MyClass()
{
// Initialization goes here.
}
public void Foo()
{
// ...
}
public void Bar()
{
// ...
}
}
static void Main(string[] args)
{
MyClass.Current.Foo(); // Initialization only performed here.
MyClass.Current.Bar();
MyClass.Current.Foo();
}
Edit: I did some further reading up on the matter, and it appears that static constructors do cause deadlocks if you perform blocking operations (e.g. asynchronous callbacks or thread synchronization) within them.
The CLR internally uses locking to prevent type initializers (static constructors) from being executed multiple times concurrently. Thus, if your static constructor attempts to access another member of its declaring type from another thread, it would inevitably deadlock. Since “another member” could be an anonymous function declared as part of a PLINQ or TPL operation, these bugs can be subtle and hard to identify.
Igor Ostrovsky (MSFT) explains this in his Static constructor deadlocks article, providing the following example of a deadlock:
using System.Threading;
class MyClass
{
static void Main() { /* Won’t run... the static constructor deadlocks */ }
static MyClass()
{
Thread thread = new Thread(arg => { });
thread.Start();
thread.Join();
}
}
In the above example, the new thread needs to access the empty anonymous function, { }, defined as its callback. However, since the anonymous function is compiled as another private method of MyClass behind the scenes, the new thread cannot access it before the MyClass type initializes. And, since the MyClass static constructor needs to wait for the new thread to complete first (because of thread.Join()), a deadlock ensues.

Yes, there are some pitfalls, mostly related to when the class is initialized. Basically, a class with a static constructor will not be marked with the beforefieldinit flag, which allows the runtime to initialize it at a later time.
Have a look at this article for more details.

This is not an answer to the question, but it's too long for a comment, so I offer it here...
Since I didn't know for static class construct, I have used following scheme (simplified) to provide me with singletons:
public class SomeSingleton {
static _instance;
static public SomeSingleton Instance {
get {
if (_instance==null) {
_instance=new SomeSingleton();
}
return _instance;
}
}
}
Later, you use
SomeSingleton.Instance.MyProp = 3;
And first usage of the Instance member will construct your singleton.
I guess that it is OK since instantiation of the singletons if there are many of such classes is done in proper order.

Related

Is the following C# Code Thread-safe in a multi-threaded evironment?

Since I create the readonly static instance as soon as someone uses the class, no lazy loading, this code is thread safe and I do not need to follow the Double-checked locking design pattern, correct?
public class BusSingleton<T> where T : IEmpireEndpointConfig, new()
{
private static readonly BusSingleton<T> instance = new BusSingleton<T>();
private IBus bus;
public IBus Bus
{
get { return this.bus; }
}
public static BusSingleton<T> Instance
{
get
{
return instance;
}
}
private BusSingleton()
{
T config = new T();
bus = NServiceBus.Bus.Create(config.CreateConfiguration());
((IStartableBus) bus).Start();
}
}
During the static initializer the run-time puts a lock around the object's type so two instances of the initializer can not be run at the same time.
The only thing you must be careful of is if NServiceBus.Bus.Create, config.CreateConfiguration, or bus.Start() use multiple threads internally and try to access your object's type anywhere within the class/function on that other thread you could deadlock yourself if one of those three function calls does not return until after that internal thread is done.
When you do the traditional "lazy singleton" with double checked locking the static initializer will have already finished and you don't run the risk of deadlocking yourself.
So if you are confidant that those 3 functions will not try to access your type on another thread then it is fine to not use double checked locking for your use case.
That looks safe as long as you don't need to delay the instantiation to run initalization code or anything like that. Which it sounds like you don't need.
https://msdn.microsoft.com/en-us/library/ff650316.aspx

Thread safe Singletion static method initialization

I'm implementing a singleton pattern, and need the initialization to be thread safe.
I've seen several ways to do it, like using the double check lock implementation, or other techniques (i.e.: http://csharpindepth.com/articles/general/singleton.aspx)
I wanted to know if the following approach, which is similar to the fourth version in the article, is thread safe. I'm basically calling a method in the static field initializer, which creates the instance. I don't care about the lazyness. Thanks!
public static class SharedTracerMock
{
private static Mock<ITracer> tracerMock = CreateTracerMock();
private static Mock<ITracer> CreateTracerMock()
{
tracerMock = new Mock<ITracer>();
return tracerMock;
}
public static Mock<ITracer> TracerMock
{
get
{
return tracerMock;
}
}
}
Yes, that's thread-safe - although it's not the normal singleton pattern, as there are no instances of your class itself. It's more of a "single-value factory pattern". The class will be initialized exactly once (assuming nothing calls the type initializer with reflection) and while it's being initialized in one thread, any other thread requesting TracerMock will have to wait.
Your code can also be simplified by removing the method though:
public static class SharedTracerMock
{
private static readonly Mock<ITracer> tracerMock = new Mock<ITracer>();
public static Mock<ITracer> TracerMock { get { return tracerMock; } }
}
Note that I've made the field readonly as well, which helps in terms of clarity. I generally stick trivial getters all on one line like this too, to avoid the bulk of lots of lines with just braces on (7 lines of code for one return statement feels like overkill).
In C# 6, this can be simplified even more using a readonly automatically implemented property:
public static class SharedTracerMock
{
public static Mock<ITracer> TracerMock { get; } = new Mock<ITracer>();
}
Of course, just because this property is thread-safe doesn't mean that the object it returns a reference to will be thread-safe... without knowing about Mock<T>, we can't really tell that.

Is the static initialization order of this code implementation specific?

I have a design that relies heavily on static initialization. I've noticed that after a series of OS updates, my design appears to be failing on some older versions of the .NET Framework (v<3.5), and only under Release configuration.
I think I've been able to narrow the issue down to a block of code similar in design to this:
public abstract class Foo { public static object A; }
public class Bar : Foo {
public static object B = InitB();
private static object InitB(){ return A }; }
public static void Main()
{
Foo.A = new object();
Bar bar = new Bar();
Console.Write((bar.B==null).ToString());
}
On .NET 2.0, under Release build, on my system, it appears my code is printing true. Whereas on .NET 4.5, it's printing false. Is the behavior of the code above implementation specific?
Your code relies on Bar's static constructor being called after the assignment to Foo.A. The language spec does not guarantee this. It only guarantees it if you actually write a static constructor, not if the compiler implicitly generates one: in that case, it may be called earlier than you expect.
To make sure your code behaves the same way in all valid implementations of .NET Framework, add a static constructor. You don't need to re-factor your initialisers, they can remain where they are.
public class Bar : Foo {
static Bar() { } // <-- add this
public static object B = InitB();
private static object InitB() { return A };
}
Alternatively, re-work your code in such a way that it still works even if the static constructor is called early.
Is the behaviour of the above code implementation specific
For the example above, the docs would suggest that is the case
If a static constructor exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.
For consistency across .NET versions, and to force initialization order, you should add a static constructor to both classes.

Is it good practice to lock on a threaded instance of an object being used throughout an application?

Every example I've ever seen of locking uses a private object to lock specific blocks of code, and Thread Synchronization (C#) gives the same kind of example, but also says "Strictly speaking, the object provided is used solely to uniquely identify the resource being shared among multiple threads, so it can be an arbitrary class instance. In practice, however, this object usually represents the resource for which thread synchronization is necessary." (Emphasis mine.) In my example here, and in my code, there is only one instance of "MyClass", which is running on its own thread, and a reference to it is passed around to various other classes.
Is it OK to lock on the MyClass reference and then call Ready(), or should I instead put a private object() within MyClass and lock on that, as shown in the LockedReady() method? Thank you for your answer, in advance.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var uc = new UserClass();
uc.DoThings();
}
}
public class MyClass
{
public bool Ready()
{
//determine if the class is ready to perform its function
//assumes that the instance of MyClass is locked,
//as shown in UserClass.DoThings
}
private object _readyLock = new object();
public bool LockedReady()
{
lock (_readyLock)
{
//determine if the class is ready to perform its function
//no assumption made that the object is locked, as
//shown in AnotherClass.DoAnotherThing()
}
}
}
public class UserClass
{
private MyClass _myc;
public UserClass()
{
var t = new Thread(SetupMyClass);
t.Start();
}
private void SetupMyClass()
{
_myc = new MyClass();
}
public void DoThings()
{
lock(_myc)
{
if (_myc.Ready())
{
//Do things
}
}
}
public void DoOtherThings()
{
var ac = new AnotherClass(_myc);
ac.DoAnotherThing();
}
}
public class AnotherClass
{
private MyClass _myc;
public AnotherClass(MyClass myClass)
{
_myc = myClass;
}
public void DoAnotherThing()
{
if (_myc.LockedReady())
{
//do another thing
}
}
}
}
Functionally, it doesn't matter, one object doesn't perform better than the other, unless there is shared use of that object by other locking concerns.
With C#, it isn't uncommon to lock on the actual domain object, rather than a surrogate object for the lock. It is also common to see a member object used, and a common legacy example is the SyncRoot object on the early System.Collections. Either way works, as long as you use a reference type.
However, the argument to be made for using an internal surrogate lock object is one of encapsulation. It eliminates the possibility of external interference if a user of your class decides to use your class as a lock. Using an internal lock object protects your locks from external interference, so one could argue that locking is an implementation detail that should be hidden.
The important thing is to ensure it is correct and appropriate. Make sure your locking is done at an appropriate granularity. (For example, using a static lock object probably isn't the best approach for a non-singleton, and probably not even most singletons). In cases where your class has multiple mutually exclusive threaded operations, you don't want to lock on "this" or you have unnecessary contention. That is like having one red light for 2 non-overlapping intersections.

Is static constructor really thread safe?

My code:
using System;
using System.Diagnostics;
using System.Threading.Tasks;
public class Program
{
private static void Main(string[] args)
{
var test = new Test(); // TypeInitializationException?
var test2 = new Test();
}
public class Test
{
public Test()
{
Trace.WriteLine("Test Created");
}
static Test()
{
Task.Factory.StartNew(
() =>
{
throw new Exception();
});
}
}
}
If I change the static const to :
static Test()
{
throw new Exception();
}
Then it is throwing TypeInitializationException! I thought static constructor is thread safe?
Is the C# static constructor thread safe?
private static void Main(string[] args)
{
Task.Factory.StartNew(
() =>
{
var test = new Test();
});
var test2 = new Test(); // HERE I GET THE EXCEPTION!!!!
}
public class Test
{
public Test()
{
Trace.WriteLine("Test Created");
}
static Test()
{
throw new Exception();
}
}
}
Thread safe is not a particularly helpful phrase to use. You should generally avoid using it as it doesn't really tell you what operations are and are not safe.
Instead it's important to specifically state what thread-related operations and situations are supported in any given context. One can then objectively and clearly state whether the expectations are violated.
C# will ensure that static constructors are run at some point before they are used, no matter how many threads might use the class, or whether another thread is currently running the static constructor.
C# will ensure that it doesn't run the static constructor more than once, no matter how many different threads might be using the same class at around the same time, or whether another thread uses a class while it is currently being initialized.
The specs specifically state that if a static constructor throws an exception in the one time that it runs then all future uses of that type will throw a TypeInitializationException, which is what you are seeing.
The behavior that you are seeing is entirely in line with the behavior defined in the specifications.
Thread-safe in this context only means that you don't need to worry about two threads invoking the static constructor at the same time, or one thread starting the static constructor, and a second thread thinking it has run and skipping the constructor, even though it hasn't finished (causing access to uninitialized fields).
If you throw an exception in the constructor, that is simply an error. Nothing to do with thread safety. Type initialization errors are very bad, and will keep happening until the static constructor can successfully complete.
Static constructor wraps all exceptions which are thrown inside into TypeInitializationException and that doesn't have relation to thread safety.
It is guaranteed that constructor is executed once and only once, before first usage of a type (or no execution if type isn't used) not depending on how many threads access the type. This means it is thread safe.

Categories

Resources