I can't reproduce the issue. The program below creates 5 Foo
instances in parallel, and the constructor of each Foo
instance uses as a lock a static instance of a class SlowObject
, that needs 500 msec for its instantiation. Nevertheless the SlowObject
is always created before any Foo
constructor is started. I tested this program with various versions of .NET Framework, C# versions 4, 5, 6 an 7, with both Debug and Release configurations, and with and without debugger attached. The output is always the same. Commenting out the static constructors makes no difference.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Threading;
class Program
{
static Program()
{
Program.ConsolePrint("Program Static Constructor");
}
static void Main(string[] args)
{
ConsolePrint("Starting Tasks");
var tasks = Enumerable.Range(1, 5).Select(n => Task.Run(() =>
{
new Foo(n.ToString());
})).ToArray();
ConsolePrint("Waiting Tasks");
Task.WaitAll(tasks);
ConsolePrint("Tasks Finished");
//Console.WriteLine("Foo.list: " + String.Join(", ", Foo.GetItems()));
}
public static void ConsolePrint(string line)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss.fff") + " ["
+ Thread.CurrentThread.ManagedThreadId.ToString() + "] > " + line);
}
}
public class Foo
{
static Foo()
{
Program.ConsolePrint("Foo Static Constructor");
}
private static List<string> list = new List<string>();
private static object listLock = new SlowObject();
public Foo(string s)
{
Program.ConsolePrint("Creating Foo " + s);
lock (listLock)
{
list.Add(s);
}
}
}
public class SlowObject
{
static SlowObject()
{
Program.ConsolePrint("SlowObject Static Constructor");
}
public SlowObject()
{
Program.ConsolePrint("SlowObject Instance Constructor Started");
Thread.Sleep(500);
Program.ConsolePrint("SlowObject Instance Constructor Finished");
}
}
Output:
13:40:24.091 [1] > Program Static Constructor
13:40:24.112 [1] > Starting Tasks
13:40:24.131 [1] > Waiting Tasks
13:40:24.132 [3] > SlowObject Static Constructor
13:40:24.133 [3] > SlowObject Instance Constructor Started
13:40:24.635 [3] > SlowObject Instance Constructor Finished
13:40:24.635 [3] > Foo Static Constructor
13:40:24.637 [3] > Creating Foo 1
13:40:24.637 [4] > Creating Foo 2
13:40:24.643 [3] > Creating Foo 5
13:40:24.639 [5] > Creating Foo 3
13:40:24.641 [6] > Creating Foo 4
13:40:24.647 [1] > Tasks Finished
Press any key to continue . . .