博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#AutoResetEvent和ManualResetEvent的区别
阅读量:5782 次
发布时间:2019-06-18

本文共 4240 字,大约阅读时间需要 14 分钟。

一:终止状态和非终止状态    首先说说线程的终止状态和非终止状态。AutoResetEvent和ManualResetEvent的构造函数中,都有bool变量来指明线程的终止状态和非终止状态。true表示终止状态(个人理解也就是可运行状态,根据理解应该是该线程的阻塞终止了),false表示非终止状态。
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); //Thread.Sleep(Int32)是批当前进程挂起3000毫秒,与线程t1是一点关系也没有的。            _autoResetEvent.Set();         }        void Thread1Foo()         {             _autoResetEvent.WaitOne();             MessageBox.Show("t1 end");         }     这段代码的执行结果,就是3秒钟过后,弹出“t1 end”。     而如果把:     AutoResetEvent _autoResetEvent = new AutoResetEvent(false);     改为:     AutoResetEvent _autoResetEvent = new AutoResetEvent(true);     则“t1 end”将会立刻弹出。     也就是说,在终止状态中,_autoResetEvent.WaitOne()是不会起到阻滞工作线程的作用的。(PS:ManualResetEvent也同样)二:AutoResetEvent和ManualResetEvent的区别

       AutoResetEvent 允许线程通过发信号互相通信。 通常,当线程需要独占访问资源时使用该类。

       线程通过调用 AutoResetEvent 上的  来等待信号。 如果 AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 来通知资源可用。

       调用 Set 向 AutoResetEvent 发信号以释放等待线程。 AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。 如果没有任何线程在等待,则状态将无限期地保持      为终止状态如果当 AutoResetEvent 为终止状态时线程调用 ,则线程不会被阻止。 AutoResetEvent 将立即释放线程并返回到非终止状态

 

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");         }     该段代码运行的效果是,过3秒后,要么弹出“t1 end”,要么弹出“t2 end”,不会两个都弹出。也就是说,其中一个进行将会结束,而另一个进程永远不会结束。代码段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");         }     该段代码运行的效果是,过3秒后,“t1 end”和“t2 end”,两个都被弹出。也就是说,两个进程都结束了。     这个特性就是说,AutoResetEvent只会给一个线程发送信号,而不会给多个线程发送信号。在我们需要同步多个线程的时候,就只能采用ManualResetEvent了。至于深层次的原因是,AutoResetEvent在set()之后,会将线程     状态自动置为false,而ManualResetEvent在Set()后,线程的状态就变为true了,必须手动ReSet()之后,才会重新将线程置为false。这也就是为什么他们的名字一个为Auto,一个为Manual的原因。为了更加充分的验证Manua  lResetEvent的这点特性,我们再来看代码片段4代码片段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");             //睡1S,用于等待主线程_menuRestEvent.Reset();             Thread.Sleep(1000);             _menuRestEvent.WaitOne();             MessageBox.Show("t1 step2 end");         }        void Thread2Foo()         {             _menuRestEvent.WaitOne();             MessageBox.Show("t2 step1 end");             //睡1S,用于等待主线程_menuRestEvent.Reset();             Thread.Sleep(1000);             _menuRestEvent.WaitOne();             MessageBox.Show("t2 step2 end");         }     在代码片段4中,我们对//_menuRestEvent.Reset()进行了注释,也就是说, _menuRestEvent.Set()后,线程的状态就是true状态的,程序运行的结果是"t1 step1 end"、"t1 step2 end"、"t1 step2 end"、"t2 step2 end"在3秒之后全部弹出。    而如果我们将//_menuRestEvent.Reset()的注释去掉,会发现"t1 step2 end"和"t2 step2 end"永远不会弹出。除非我们在主线程中再次对_menuRestEvent进行Set()。

  

转载地址:http://cscyx.baihongyu.com/

你可能感兴趣的文章
这些Java面试题必须会-----鲁迅
查看>>
Linux 常用命令
查看>>
NodeJS 工程师必备的 8 个工具
查看>>
CSS盒模型
查看>>
ng2路由延时加载模块
查看>>
使用GitHub的十个最佳实践
查看>>
脱离“体验”和“安全”谈盈利的游戏运营 都是耍流氓
查看>>
慎用!BLEU评价NLP文本输出质量存在严重问题
查看>>
基于干净语言和好奇心的敏捷指导
查看>>
Node.js 2017企业用户调查结果发布
查看>>
“软”苹果水逆的一周:杂志服务崩溃,新机型遭泄露,芯片首架离职
查看>>
JAVA的优势就是劣势啊!
查看>>
ELK实战之logstash部署及基本语法
查看>>
帧中继环境下ospf的使用(点到点模式)
查看>>
BeanShell变量和方法的作用域
查看>>
LINUX下防恶意扫描软件PortSentry
查看>>
由数据库对sql的执行说JDBC的Statement和PreparedStatement
查看>>
springmvc+swagger2
查看>>
软件评测-信息安全-应用安全-资源控制-用户登录限制(上)
查看>>
我的友情链接
查看>>