下面这段代码来自网上 ManualResetEvent和AutoResetEvent用法小试
对下面的代码有几个要说明的:
1 myThread.Join() 只对单一个线程,而且用在调用MyThread线程里,ManualResetEvent 可以等待多个线程
2 myThread.Abort();线程在线这个方法时,并没有真正的中止线程 , 所以在后面还要加上Join
myThread.Join();
3 请注意别外一些资源竞争的类或方法 mutex lock monitor 请注意他的同异!C#中运用Monitor类、Lock和Mutex类来同步多线程地执行
(下面如果把共享资源(nSubOne)的操作放到同一个函数里的话, 那么可以用Metux配合monitor 或者Lock 来实现)
4 另外的几个线程的函数 请参看.net 多线程初步(1)
using System; using System.Collections.Generic; using System.Text; using System.Threading; namespace ManualAndAutoResetEventTest { /// <summary> /// 此类使用了ManualResetEvent,和AutoResetEvent /// 功能一:ManualResetEvent用于,等待所有线程结束再执行 /// 功能二:AutoResetEvent用于线程间的同步 /// </summary> class Program { #region === Filed === //定义两个资源 static int nSubOne = 20; static int nSubTwo = 15; //设置手动重置信号量 //而ManualResetEvent 的Set()则不会使处于WaitOne()状态的线程自动为ReSet()的无信号状态.如果想其处于无信号状态,必须手动调用ReSet()方法. ManualResetEvent manA; ManualResetEvent manB; //设置自动重置信号量 // 下面设置为false 后 ThreadTwo()中要有ateA.set()不然程序一直阻塞 //AutoResetEvent的Set()只允许一个线程运行.也就是说AutoResetEvent的Set()方法,只会使一个线程得到运行,而使其它处于WaitOne()状态的线程自动为ReSet()的无信号状态. AutoResetEvent ateA = new AutoResetEvent(false);//这个是设置初始状态 false表示waitone 而true 的话就是set AutoResetEvent ateB = new AutoResetEvent(false ); #endregion === Filed === #region === Main Method === static void Main(string[] args) { Program pg = new Program(); pg.ThreadTest(); Console.ReadLine(); } #endregion === Main Method === #region === Private Method === void ThreadTest() { //初始化信号量 manA = new ManualResetEvent(false);//这个是设置初始状态 false表示waitone 而true 的话就是set manB = new ManualResetEvent(false); //启动两个线程 Thread thdOne = new Thread(new ThreadStart(ThreadOne)); thdOne.Start(); Thread thdTwo = new Thread(new ThreadStart(ThreadTwo)); thdTwo.Start(); //等信号量manA,manB都释放了,才执行主线程 WaitHandle.WaitAll(new WaitHandle[2] { manA, manB }); int n = 0; while (n < 10) { Console.WriteLine(n++); Thread.Sleep(50); } } void ThreadOne() { while (nSubOne > 0) { ateA.WaitOne(); //ateA保持等待 Console.WriteLine("T___1___:" + nSubOne--); ateB.Set(); //给ateB一个开始信号 Thread.Sleep(500); //可以看出,线程一和线程2的Sleep时间并不一样,但是结果仍然是对的, //这就是我们设置的同步信号量AutoResetEvent ateA,ateB的效果 } manA.Set(); //给manA一个开始信号 } void ThreadTwo() { //*****************给A一个开始信号这个非常重要 , 如果下面这一句被注释掉了话,程序将一直在等待当中 //ateA.Set(); //给ateA一个开始信号 //while (nSubTwo > 0) //可以在这试一下另一个线程操作,看是否主线程的确是等所有其它线程都执行完成才执行的. //即看一下WaitHandle.WaitAll是否是真的有效了. while (nSubOne > 0) { ateB.WaitOne(); //ateB保持等待 //Console.WriteLine("T___2___:" + nSubTwo--); Console.WriteLine("T___2___:" + nSubOne++); ateA.Set(); //给ateA一个开始信号 Thread.Sleep(1); } manB.Set(); //给manB一个开始信号 } #endregion === Custom Method === } }