In my code below, the Id property of ThreadClass is not set deterministically as expected (ThreadArray[0]'s ThreadClass.Id = 0, ThreadArray[1]'s ThreadClass.Id = 1, etc).
If I debug and slow down the Thread.Start()'s, everything works as expected. But when the program runs at full-speed, I get all Id's = 4 (or similar). I can’t lock i because it’s not a reference variable. Clearly, I am encountering a race condition. What am I doing wrong?
Main.cs
for (int i = 0; i < ThreadCount; i++)
{
ThreadArray[i] = new Thread(() =>
{
new ThreadClass(i);
});
ThreadArray[i].Start();
}
ThreadClass.cs
private int Id { get; set; }
public ThreadClass(int i) {
Id = id;
while(true)
{
Console.WriteLine("I am thread " + i");
Thread.Sleep(5000);
}
}
Expected output:
I am thread 0
I am thread 1
I am thread 2
I am thread 3
... 5 second wait ...
I am thread 0
I am thread 1
I am thread 2
I am thread 3
Actual output:
I am thread 4
I am thread 4
I am thread 4
I am thread 4
... 5 second wait ...
I am thread 4
I am thread 4
I am thread 4
I am thread 4
Note that at this point each instance of ThreadArray is initialized to a valid Thread object.
You’re using a version of C# that doesn’t close over a fresh copy of the
ivariable. By the time the threads are executed,iis at or nearThreadCount. Simply create a copy of the variable so the closure can capture that instead:By the way, the version of C# in VS 2012 (or .NET 4.5) fixes this. See http://msdn.microsoft.com/en-us/library/hh678682(v=vs.110).aspx