Have you programmed a multi-threaded application?
How many times have you wrote the following lines:
Thread t1 = new Thread(() => Console.WriteLine("Thread 1 working"));
t1.Start();
// do some work
Thread.Sleep(5000);
// continue execution
or this code snippet:
while (someArgument == true)
{
Thread.Sleep(10);
}
If never – good for you!
The problem is that many programmers when confronted with the need to sync actions in different threads use a similar code construct.
Both code snippets shows a solution to a similar problem – wait until an action happens in another thread before continuing the current thread execution.
So I shouldn’t use Sleep?
No, there is nothing wrong with using Thread.Sleep when needed. However the examples above shows how it can been misused.
- The 1st snippet shows Sleep as a way to wait till a thread has done some work and exited.
Using Sleep introduce an unknown/random factor to your code.
What happens if the created thread didn’t finish before the sleep – should we increase the wait time? - The 2nd snippet shows sleep as a way to sync two threads.
Another thread change someArgument value an action has been performed. However CPU cycles are wasted checking the argument before each sleep.
There are better ways to solve those problems:
1. Use Thread.Join
2. EventWaitHandle
Thread.Join
We use Join when we want to wait till another thread ends.
Thread t1 = new Thread(() => Console.WriteLine("Thread 1 working"));
t1.Start();
// do some work
t1.Join();
// continue execution
No random results – a simple solution that always works.
EventWaitHandle
EventWaitHandle has very low CPU overhead and should can be to used to pause a thread until a signal is received.
static EventWaitHandle waitEventHandle = new AutoResetEvent(true);
public void DoWork()
{
Console.WriteLine("Thread 1 working");
// Do Some Work
waitEventHandle.Set();
// Do more Work
}
public void WaitThread()
{
new Thread(DoWork).Start();
waitEventHandle.WaitOne();
//…
}
In this code snippet instead of using a loop and a shared variable we use AutoResetEvent so that WaitThreadthread can wait until DoWork thread signals.
Comment?