As most of you correctly highlighted, the last exercise exhibits a deadlock situation. The main thread here simply creates and starts another thread and waits for its completion, but this expectation is never fulfilled.
class Program
{
static void Main(string[] args)
{
var workerThread = new Thread(Worker);
workerThread.Start();
workerThread.Join();
}
...
When one looks at the worker thread code, you realize that the stopping condition is never going to be met: Thread.CurrentThread.IsAlive just cannot be false! The current thread is alive, otherwise it will be dead, hence not executing code.
...
static void Worker()
{
while (Thread.CurrentThread.IsAlive)
{
Console.Write("Blah");
}
}
}
Based on a true story, this example shows a very common misconception, that the framework provides facilities to control the life cycle of threads, and for that matter that Join will trigger a graceful stop. Well, sorry to break this to you guys, this is just not happening. It is your responsibility to implement an appropriate mechanism.
Here is a valid implementation using a shared flag:
public class Solution
{
private readonly object synchro = new object();
private bool run;
static void Main(string[] args) {
var workerThread = new Thread(Worker);
run = true;
workerThread.Start();
lock (this.synchro) {
run = false;
}
// wait for the thread to start
workerThread.Join();
}
private void Worker() {
for (;;) {
lock (this.synchro) {
if (!run) {
break;
}
}
Console.Write("Blah ");
}
}
}
New! Available on GitHub: for the curious, the critics and the laziest, I have but the code on GitHub as a VS 2012 solution.
Related articles
- Can you spot the deadlock 4 ?! (dupdob.wordpress.com)


