In the last few hours, I hit that head, so that's it. Maybe this is a common mistake for someone who has little experience with multithreading? Who knows.
In the included code, I create three threads that trigger the DisplayValues ββ(DateTime Now, int Period) method. The debugger stops three times in each of the IF statements, and for each it calls the method with the correct values. The problem is that Console.WriteLine displays erratic values ββthat are completely different from how the calls were made.
The console calls DisplayValues ββ() 3 times with the following parameters, which is correct: DisplayValues('{5/8/2014 4:20:00 AM}', 0); DisplayValues('{5/8/2014 4:35:00 AM}', 1); DisplayValues('{5/8/2014 4:50:00 AM}', 2);
But the conclusion is completely different:
5/8/2014 4:35:00 AM Period: 0
5/8/2014 4:50:00 AM Period: 1
5/8/2014 4:51:00 AM Period: 2
The debugger confirms this. Since this is a console application, I thought it might be that all methods were static, so I moved DisplayValues ββ() to a class. Then I thought that all three instances of the class have the same name, so I changed the name. Then I thought it could be a CancellationTokenSource object, so I also deleted it.
Needless to say, that without threads, the result is correct.
I know that there is an obvious reason, I just donβt know what it is.
Any help is appreciated. Thanks.
bool thread0Running = false; bool thread1Running = false; bool thread2Running = false; DateTime DateNow = new DateTime(2014, 5, 8, 4, 0, 0); while ((!thread0Running || !thread1Running || !thread2Running) && DateNow.Hour == 4) { if ((DateNow.Hour == TaskDateTime.Hour) && (DateNow.Minute == 20)) { thread0Running = true; Class myClass0 = new Class(); new Thread(() => myClass0.DisplayValues(DateNow, 0, cts0.Token)).Start(); } else if ((DateNow.Hour == TaskDateTime.Hour) && (DateNow.Minute == 35)) { thread1Running = true; Class myClass1 = new Class(); new Thread(() => myClass1.DisplayValues(DateNow, 1, cts1.Token)).Start(); } else if ((DateNow.Hour == TaskDateTime.Hour) && (DateNow.Minute == 50)) { thread2Running = true; Class myClass2 = new Class(); new Thread(() => myClass2.DisplayValues(DateNow, 2, cts2.Token)).Start(); } DateNow = DateNow.AddMinutes(1); } public void DisplayValues(DateTime Now, int Period, Object obj) { Console.WriteLine(Now.ToString() + " Period: " + Period.ToString()); }