First, let's talk about the termination and non-termination states of the thread. Both autoresetevent and manualresetevent constructors have bool variables to indicate the termination and non-termination statuses of the thread. True indicates the termination status, and false indicates the non-termination status. ViewCodeSegment 1:
Code snippet 1:
Autoresetevent _ autoresetevent = new autoresetevent (false );
Private void bt_temp_click (Object sender, routedeventargs E)
{
Thread T1 = new thread (this. thread1foo );
T1.start ();
Thread. Sleep (3000 );
_ Autoresetevent. Set ();
}
Void thread1foo ()
{
_ Autoresetevent. waitone ();
MessageBox. Show ("T1 end ");
}
The execution result of this code is "T1 end" after three seconds ".
If you set:
Autoresetevent _ autoresetevent = new autoresetevent (false );
Changed:
Autoresetevent _ autoresetevent = new autoresetevent (true );
Then "T1 end" will pop up immediately.
In other words, in the terminated state, _ autoresetevent. waitone () does not block the working thread. (PS: manualresetevent)
Ii. Differences between autoresetevent and manualresetevent
Next, let's take a look at the differences between autoresetevent and manualresetevent. We can see code snippet 2 and code snippet 3:
Code Segment 2:
Autoresetevent _ autoresetevent = new autoresetevent (false );
Private void bt_temp_click (Object sender, routedeventargs E)
{
Thread T1 = new thread (this. thread1foo );
T1.start ();
Thread t2 = new thread (this. thread2foo );
T2.start ();
Thread. Sleep (3000 );
_ Autoresetevent. Set ();
}
Void thread1foo ()
{
_ Autoresetevent. waitone ();
MessageBox. Show ("T1 end ");
}
Void thread2foo ()
{
_ Autoresetevent. waitone ();
MessageBox. Show ("T2 end ");
}
The effect of running this section of code is that after 3 seconds, either "T1 end" or "T2 end" will pop up, and neither of them will pop up. That is to say, one of the processes will end, and the other process will never end.
Code Segment 3:
Manualresetevent _ menurestevent = new manualresetevent (false );
Private void bt_temp_click (Object sender, routedeventargs E)
{
Thread T1 = new thread (this. thread1foo );
T1.start ();
Thread t2 = new thread (this. thread2foo );
T2.start ();
Thread. Sleep (3000 );
_ Menurestevent. Set ();
}
Void thread1foo ()
{
_ Menurestevent. waitone ();
MessageBox. Show ("T1 end ");
}
Void thread2foo ()
{
_ Menurestevent. waitone ();
MessageBox. Show ("T2 end ");
}
The result of this Code section is that after three seconds, "T1 end" and "T2 end" are displayed. That is to say, both processes are finished.
This feature means that autoresetevent only sends signals to one thread rather than to multiple threads. When we need to synchronize multiple threads, we can only use manualresetevent. The underlying reason is that autoresetevent automatically sets the thread status to false after set (), while manualresetevent changes to true after set, the thread is set to false again only after manual reset. That is why their names are auto and manual. To fully verify this feature of manualresetevent, let's look at code snippet 4.
Code snippet 4:
Manualresetevent _ menurestevent = new manualresetevent (false );
Private void bt_temp_click (Object sender, routedeventargs E)
{
Thread T1 = new thread (this. thread1foo );
T1.start ();
Thread t2 = new thread (this. thread2foo );
T2.start ();
Thread. Sleep (3000 );
_ Menurestevent. Set ();
// _ Menurestevent. Reset ();
}
Void thread1foo ()
{
_ Menurestevent. waitone ();
MessageBox. Show ("T1 Step1 end ");
// Sleep for 1 s, used to wait for the main thread _ menurestevent. Reset ();
Thread. Sleep (1000 );
_ Menurestevent. waitone ();
MessageBox. Show ("T1 step2 end ");
}
Void thread2foo ()
{
_ Menurestevent. waitone ();
MessageBox. Show ("T2 Step1 end ");
// Sleep for 1 s, used to wait for the main thread _ menurestevent. Reset ();
Thread. Sleep (1000 );
_ Menurestevent. waitone ();
MessageBox. Show ("T2 step2 end ");
}
In code snippet 4, we commented on // _ menurestevent. Reset (), that is, after _ menurestevent. Set (), the thread state is true,ProgramThe running results are "T1 Step1 end", "T1 step2 end", "T1 step2 end", and "T2 step2 end", all of which will pop up after 3 seconds.
if we remove the comments of // _ menurestevent. Reset (), we will find that "T1 step2 end" and "T2 step2 end" will never pop up. Unless we perform set () on _ menurestevent again in the main thread ().