I think the problem is purely that you are performing a blocking operating inside a type initializer. The CLR has to run type initializers inside a lock, as it has to prevent them from ever being run twice, and it uses the same lock for all types. If you do threading inside your type initializer, and you block, then you risk deadlock.

I think that's exactly what's happening here:

The main thread grabs the type initializer lock and runs the type initializer Another thread is spawned, which accesses the Convert class, which needs to run its type initializer. So it tries to grab the type initializer lock The main thread blocks waiting for the second thread to complete, holding the type initializer lock Deadlock

You didn't see this when calling IConvertable.ToUInt64 directly, because that didn't need to call the Convert class's type initializer.

When your TestClass<T>.Instance is assigned inline, the BeforeFieldInit flag gets set. This means the CLR uses a relaxed approach to running the type initializer, and in my testing it ran it before Main , before the type initializer for Convert had been run. When you defined an explicit static constructor, the CLR was forced to run the type initializer when TestClass<T>.Instance was first referenced in Main , presumably after Convert had been initialized, which happened to avoid the deadlock.

My evidence for this is knowledge of how type initializers are run, the fact that the thread blocks somewhere inside the runtime (but before it gets a chance to run the method Convert.ChangeType ), and the fact that merely referencing the Convert type is enough to trigger this.

See this MSDN article. I think the takeaway is that you probably shouldn't be doing threading in your type initializer, and you definitely shouldn't be blocking the thread which is running the type initializer.

I'd be happy to take at your actual (non-simplified) problem, and try a suggest ways of improving its performance without resorting to threading in the type initializer.