今天详细说一下ManualResetEvent
它可以通知一个或多个正在等待的线程已发生事件,允许线程通过发信号互相通信,来控制线程是否可心访问资源
当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态。此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。
一旦它被终止,ManualResetEvent 将保持终止状态,直到它被手动重置。即对 WaitOne 的调用将立即返回。
上面是它的功能描述,你可能会有点晕。我会用代码一点一点解释它,看完我写的这些内容,你自己运行一下代码你就会明白它的功能
我们从初始化来开始讲
可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false。
我用代码 让大家看一下什么是终止状态和非终止状态
先看一下代码
| classProgram   {       staticManualResetEvent _mre = newManualResetEvent(false);       staticvoidMain(string[] args)       {           Thread[] _threads = newThread[3];           for(inti = 0; i < _threads.Count(); i++)           {               _threads[i] = newThread(ThreadRun);               _threads[i].Start();           }                 }       staticvoidThreadRun()       {           int_threadID = 0;           while(true)           {               _mre.WaitOne();               _threadID = Thread.CurrentThread.ManagedThreadId;               Console.WriteLine("current Tread is "+ _threadID);               Thread.Sleep(TimeSpan.FromSeconds(2));                            }       }   } | 
当初始化为true时,为终止状态
| staticManualResetEvent _mre = newManualResetEvent(true); | 
执行结果

当初始化为false时,为非终止状态
| staticManualResetEvent _mre = newManualResetEvent(false); | 
执行结果为

这样我们就能看出来
终止状态时WaitOne()允许线程访问下边的语句
非终止状态时WaitOne()阻塞线程,不允许线程访问下边的语句
我们也可以把WaitOne()放在方法最下边
| staticvoidThreadRun()        {            int_threadID = 0;            while(true)            {                                _threadID = Thread.CurrentThread.ManagedThreadId;                Console.WriteLine("current Tread is "+ _threadID);                Thread.Sleep(TimeSpan.FromSeconds(2));                _mre.WaitOne();            }        } | 
当初始化为true时执行结果和上边的一样会不停的执行

初始化为false时执行到waitOne()时就阻塞线程不会再往下执行了

接下来你可能就会想当在非终止状态时怎么让线程继续执行,怎么再让它停下来,这就要用了set()和Reset()方法了
把非终止状态改为终止状态用Set()方法
把终止状态改为非终止状态用Reset()方法
我用用代码来实现它们只要把我们上 边的代码做一下改动
| classProgram    {        staticManualResetEvent _mre = newManualResetEvent(false);        staticvoidMain(string[] args)        {            Console.WriteLine("输入1为Set()   开始运行");            Console.WriteLine("输入2为Reset() 暂停运行");            Thread[] _threads = newThread[3];            for(inti = 0; i < _threads.Count(); i++)            {                _threads[i] = newThread(ThreadRun);                _threads[i].Start();            }            while(true)            {                switch(Console.ReadLine())                {                    case"1":                        _mre.Set();                        Console.WriteLine("开始运行");                        break;                    case"2":                        _mre.Reset();                        Console.WriteLine("暂停运行");                        break;                    default:                        break;                }            }                   }        staticvoidThreadRun()        {            int_threadID = 0;            while(true)            {                                _threadID = Thread.CurrentThread.ManagedThreadId;                Console.WriteLine("current Tread is "+ _threadID);                Thread.Sleep(TimeSpan.FromSeconds(2));                _mre.WaitOne();            }        }    } | 
当输入1 时会调用 Set()方法 ManualResetEvent 处于终止状态会WaitOne不会阻塞线程会一直运行下去
当输入2时会调用 Reser()方法ManualResetEvent处于非终止状态WaitOne会阻塞线程直到再调用 Set()方法
看一下执行结果吧

文章末尾固定信息




 服务器0元试用,首购低至0.9元/月起
服务器0元试用,首购低至0.9元/月起




评论