详解 ManualResetEvent

简介:

今天详细说一下ManualResetEvent

它可以通知一个或多个正在等待的线程已发生事件,允许线程通过发信号互相通信,来控制线程是否可心访问资源

当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态。此线程可被视为控制ManualResetEvent调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。

一旦它被终止,ManualResetEvent 将保持终止状态,直到它被手动重置。即对 WaitOne 的调用将立即返回。

上面是它的功能描述,你可能会有点晕。我会用代码一点一点解释它,看完我写的这些内容,你自己运行一下代码你就会明白它的功能

源代码:ManualResetEventDemo.rar

我们从初始化来开始讲

可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false

我用代码 让大家看一下什么是终止状态和非止状态

先看一下代码

class  Program
    {
        static  ManualResetEvent _mre = new  ManualResetEvent( false );
        static  void  Main( string [] args)
        {
            Thread[] _threads = new  Thread[3];
            for  ( int  i = 0; i < _threads.Count(); i++)
            {
                _threads[i] = new  Thread(ThreadRun);
                _threads[i].Start();
            }
           
        }
 
        static  void  ThreadRun()
        {
            int  _threadID = 0;
            while  ( true )
            {
                _mre.WaitOne();
                _threadID = Thread.CurrentThread.ManagedThreadId;
                Console.WriteLine( "current Tread is "  + _threadID);
                Thread.Sleep(TimeSpan.FromSeconds(2));
                  
            }
        }
    }

当初始化为true时,为终止状态

static  ManualResetEvent _mre = new  ManualResetEvent( true );

执行结果

 

当初始化为false时,为非终止状态

static  ManualResetEvent _mre = new  ManualResetEvent( false );

执行结果为

这样我们就能看出来

终止状态时WaitOne()允许线程访问下边的语句

非终止状态时WaitOne()阻塞线程,不允许线程访问下边的语句

我们也可以把WaitOne()放在方法最下边

static  void  ThreadRun()
         {
             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()方法

我用用代码来实现它们只要把我们上 边的代码做一下改动

class  Program
     {
         static  ManualResetEvent _mre = new  ManualResetEvent( false );
         static  void  Main( string [] args)
         {
             Console.WriteLine( "输入1为Set()   开始运行" );
             Console.WriteLine( "输入2为Reset() 暂停运行" );
             Thread[] _threads = new  Thread[3];
             for  ( int  i = 0; i < _threads.Count(); i++)
             {
                 _threads[i] = new  Thread(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 ;
                 }
             }
            
         }
 
         static  void  ThreadRun()
         {
             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()方法

看一下执行结果吧

 代码:ManualResetEventDemo.rar

本文转自lpxxn博客园博客,原文链接:http://www.cnblogs.com/li-peng/p/3291306.html,如需转载请自行联系原作者

相关文章
|
4月前
|
C#
C# | 使用AutoResetEvent和ManualResetEvent进行线程同步和通信
在多线程编程中,AutoResetEvent 和 ManualResetEvent 是两个常用的同步原语。它们用于线程间的通信和协调,以确保线程按照特定的顺序执行。本篇博客将介绍这两种同步原语的概念、用法和区别。
46 0
C# | 使用AutoResetEvent和ManualResetEvent进行线程同步和通信
C#深入理解AutoResetEvent和ManualResetEvent
当在C#使用多线程时就免不了使用AutoResetEvent和ManualResetEvent类,可以理解这两个类可以通过设置信号来让线程停下来或让线程重新启动,其实与操作系统里的信号量很相似(汗,考完考试已经有点忘记了)。
1852 0
|
API iOS开发
RunLoop
简介 什么是 RunLoop ? 从字面意思看的话是运行循环、跑圈的意思; RunLoop 的基本作用是什么: 保持程序的持续运行; 处理 App 中的各种事件(比如触摸事件、定时器事件、Selector 事件); 节省 CPU 资源,提高程序性能:...
1111 0
runloop理解和剖析
http://www.jianshu.com/p/edbe946c8a11
834 0