So I was happily reading this from Eric Lippert and then, of course, the excellent comments and in them John Payson said:
a more interesting example might have been to use two static classes, since such a program could deadlock without any visible blocking statements.
and I thought, yeah, that'd be easy so I knocked up this:
public static class A
{
static A()
{
Console.WriteLine("A.ctor");
B.Initialize();
Console.WriteLine("A.ctor.end");
}
public static void Initialize()
{
Console.WriteLine("A.Initialize");
}
}
public static class B
{
static B()
{
Console.WriteLine("B.ctor");
A.Initialize();
Console.WriteLine("B.ctor.end");
}
public static void Initialize()
{
Console.WriteLine("B.Initialize");
}
public static void Go()
{
Console.WriteLine("Go");
}
}
The output of which (after calling B.Go()
) is:
B.ctor
A.ctor
B.Initialize
A.ctor.end
A.Initialize
B.ctor.end
Go
No deadlock and I am am obviously a loser - so to perpetuate the embarrassment, here is my question: why no deadlock here?
It seems to my tiny brain that B.Initialize
is called before the static constructor of B
has finished and I thought that that was not allowed.
It's not a deadlock because you're not doing anything that should block, nor are you doing anything that should break.
You are not using any resources from A
within B
, and vice versa. As a result, your circular dependency is "safe" in the sense that nothing will explode.
If you trace the path that your printouts show, then nothing should block:
Go
(I suspect)B
(static
constructor) as it is not initialized.A.Initialize()
A
's static
constructor is required to execute firstB.Initialize()
B
does not need to initialize, but it's not in a completed state (fortunately no variables are being set, so nothing breaks)A
's static
constructor), then returnA.Initialize()
can finally be called because A
is initializedB
's static
constructor), then returnGo
The only thing that you really did was present the potential for an unsafe state: accessing a class whose constructor had not finished executing. That is unsafe code, and while not blocking, definitely represents a broken state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With