.NET provides many mechanisms to help you control threads. Another way to keep a thread blocked while another thread is processing a piece of shared memory is to use an AutoResetEvent. The AutoResetEvent class has two methods, Set and WaitOne. These two methods can be used together for controlling the blocking of a thread. When an AutoResetEvent is initialized with false, the program will stop at the line of code that calls WaitOne until the Set method is called on the AutoResetEvent. After the Set method is executed on the AutoResetEvent, the thread becomes unblocked and is allowed to proceed past WaitOne. The next time WaitOne is called, it has automatically been reset, so the program will again wait (block) at the line of code in which the WaitOne method is executing. You can use this "stop and trigger" mechanism to block on one thread until another thread is ready to free the blocked thread by calling Set. Listing 3 shows our same two threads using the AutoResetEvent to block each other while the block thread waits and the unblocked thread executes to display _threadOutput to the Console. Initially, _blockThread1 is initialized to signal false, while _blockThread2 is initialized to signal true. This means that _blockThread2 will be allowed to proceed through the WaitOne call the first time through the loop in DisplayThread_2, while _blockThread1 will block on its WaitOne call in DisplayThread_1. When the _blockThread2 reaches the end of the loop in thread 2, it signals _blockThread1 by calling Set in order to release thread 1 from its block. Thread 2 then waits in its WaitOne call until Thread 1 reaches the end of its loop and calls Set on _blockThread2. The Set called in Thread 1 releases the block on thread 2 and the process starts again. Note that if we had set both AutoResetEvents (_blockThread1 and _blockThread2) initially to signal false, then both threads would be waiting to proceed through the loop without any chance to trigger each other, and we would experience a deadlock.
Listing 3 - Alternatively Blocking threads with the AutoResetEvent
AutoResetEvent _blockThread1 = new AutoResetEvent(false);
AutoResetEvent _blockThread2 = new AutoResetEvent(true);
///
/// Thread 1, Displays that we are in thread 1
///
void DisplayThread_1()
{
while (_stopThreads == false)
{
// block thread 1 while the thread 2 is executing
_blockThread1.WaitOne();
// Set was called to free the block on thread 1, continue executing the code
Console.WriteLine("Display Thread 1");
_threadOutput = "Hello Thread 1";
Thread.Sleep(1000); // simulate a lot of processing
// tell the user what thread we are in thread #1
Console.WriteLine("Thread 1 Output --> {0}", _threadOutput);
// finished executing the code in thread 1, so unblock thread 2
_blockThread2.Set();
}
}
///
/// Thread 2, Displays that we are in thread 2
///
void DisplayThread_2()
{
while (_stopThreads == false)
{
// block thread 2 while thread 1 is executing
_blockThread2.WaitOne();
// Set was called to free the block on thread 2, continue executing the code
Console.WriteLine("Display Thread 2");
_threadOutput = "Hello Thread 2";
Thread.Sleep(1000); // simulate a lot of processing
// tell the user we are in thread #2
Console.WriteLine("Thread 2 Output --> {0}", _threadOutput);
// finished executing the code in thread 2, so unblock thread 1
_blockThread1.Set();
}
}
The output produced by listing 3 is the same output as our locking code, shown in figure 3, but the AutoResetEvent gives us some more dynamic control over how one thread can notify another thread when the current thread is done processing.
find Complete Post at :
http://www.c-sharpcorner.com/UploadFile/mgold/MultithreadingIntro10062005000439AM/MultithreadingIntro.aspx
No comments:
Post a Comment