Tuesday, October 04, 2005 6:30 PM
Sandeep Prabhakar
Static Constructors
There are some things that cannot be done in .NET Compact Framework in a static constructor which are possible in the full .NET Framework. Basically, all static constructors when are executed in a serialized fashion in .NET Compact Framework V2 (Note that this design may change in future versions of the product). As a result, you can result in deadlocks if you are doing certain operations in the static constructors. Take the following program for example. Here, I have 2 threads. In the main thread, I execute a function in StaticClass1 - this calls implicitly the static ctor for StaticClass1. In this static ctor, we wait on an Event that gets set by the Static Ctor of StaticClass2 which gets executed on another thread. Since the execution of static ctors are serialized in the .NET Compact Framework's execution engine, the StaticClass1 will never signal the event and never finish. Also, StaticClass2's ctor cannot execute since we prevent both the StaticClass1's and StaticClass2's ctors from executing at the same time... deadlock is the result. This applies only to .NET Compact Framework and works fine on the .NET Framework.
using System;
using System.Threading;
using System.Net;
public class Test
{
public static SyncContainer sc = new SyncContainer();
public static StaticClass1 static1;
static void Main (string[] args)
{
Thread t = new Thread(new ThreadStart(ThreadProc));
t.Start();
static1 = new StaticClass1();
string str = static1.Func();
}
public static void ThreadProc()
{
Console.WriteLine("Executing ThreadProc");
StaticClass2.Func();
Console.WriteLine("After Executing ThreadProc");
}
}
public class StaticClass2
{
static StaticClass2()
{
Test.sc.are.Set();
}
public static string Func()
{
return "world";
}
}
public class StaticClass1
{
static StaticClass1()
{
Console.WriteLine("Executing Static Ctor");
Test.sc.are.WaitOne();
Console.WriteLine("After WaitOne");
}
public string Func()
{
return "hello";
}
}
public class SyncContainer
{
public AutoResetEvent are = new AutoResetEvent(false);
}
The solution to this problem if you have a similar situation is to take the code from the static ctor and put it in a static property/method and call that before you call anything else on that class.
This situation was found when a Web Service call was made in the static ctor. And since internally in the .NET Compact Framework's Networking code we use this paradigm of setting events to signal completion of networking transfer completion, we result in this deadlock.
This posting is provided "AS IS" with no warranties, and confers no rights.