一、ManualResetEvent类
用来使线程处于等待状态。其中有两个常用的方法:
Set():将状态置为有信号。
RestSet():将状态置为无信号。
WaitOne:等待一个事件对象变成有信号。
[STAThread] public static void Main() { ManualResetEvent manRE; manRE = new ManualResetEvent(true);//初始状态为有信号 bool state = manRE.WaitOne(5000, true);//在有信号状态下,即使设置了等待时间,线程也不会在WaitOne方法内等待 Console.WriteLine("ManualResetEvent After First WaitOne -- " + state);//True //状态改为无信号 manRE.Reset(); state = manRE.WaitOne(5000, true);//无信号状态下,线程将等待指定时长 Console.WriteLine("ManualResetEvent After second WaitOne -- " + state);//False Console.ReadLine(); }
ManualResetEvent类还有WaitAny、WaitAll,用法从字面意思就能推断出。
二、AutoResetEnvet类
用法与ManualResetEvent类类似,唯一的区别是在WaitOne方法中。执行完WaitOne方法后,信号状态自动变换。
如果将上例中的例子用AutoResetEnvet实现一下,如下:
1 public static void Main() 2 { 3 AutoResetEvent aRE; 4 aRE = new AutoResetEvent(true); //初始为终止状态 5 Console.WriteLine("Before First WaitOne"); 6 bool state = aRE.WaitOne(5000, true);//不等待(因为初始状态为终止状态),之后信号自动变为false。 7 Console.WriteLine("After First WaitOne -- " + state); 8 //状态改为无信号 9 //aRE.Reset();//不再需要手动更改信号状态。 10 state = aRE.WaitOne(5000, true); 11 Console.WriteLine("After second WaitOne -- " + state); 12 Console.ReadLine(); 13 }
三、Mutex类
Mutex类似于Monitor类,还可用于线程间同步。
1 public class NETMutex 2 { 3 static Mutex myMutex; 4 public static void Main() 5 { 6 myMutex = new Mutex(true, "WROX"); 7 NETMutex nm = new NETMutex(); 8 Thread t = new Thread(new ThreadStart(nm.Run)); 9 t.Start(); 10 Console.WriteLine("Thread sleeping for 5 secs"); 11 Thread.Sleep(5000); 12 Console.WriteLine("Thread Woke Up"); 13 myMutex.ReleaseMutex();//释放Mutex一次 14 Console.WriteLine("Before WaitOne"); 15 myMutex.WaitOne(); 16 Console.WriteLine("Lock owned by Main Thread"); 17 18 Console.ReadLine(); 19 } 20 public void Run() 21 { 22 Console.WriteLine("In Run"); 23 myMutex.WaitOne(); 24 Console.WriteLine("Thread sleeping for 10 secs"); 25 Thread.Sleep(10000); 26 Console.WriteLine("End of Run() Method"); 27 28 //如果线程终止而未释放 Mutex,则认为该 mutex 已放弃。这是严重的编程错误,因为该 mutex 正在保护的资源可能会处于不一致的状态。在 .NET Framework 2.0 版中,获取该 mutex 的下一个线程中将引发 AbandonedMutexException。 29 //这个问题是由于, 在一个子线程中,获取了mutex,但是在线程退出以前没有调用相应的ReleaseMutex方法,其他线程在等待这个mutex就会出现这个异常 30 myMutex.ReleaseMutex(); 31 } 32 }