`
wsql
  • 浏览: 11786446 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

AutoResetEvent和ManualResetEvent

 
阅读更多
首先说说线程的终止状态和非终止状态。AutoResetEvent和ManualResetEvent的构造函数中,都有bool变量来指明线程的终止状态和非终止状态。true表示终止状态,false表示非终止状态。看代码片段1:

代码片段1:

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);

_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和ManualResetEvent的区别。我们看代码段2和代码段3:

代码段2:

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的原因。为了更加充分的验证ManualResetEvent的这点特性,我们再来看代码片段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()。


分享到:
评论

相关推荐

    C#-【多线程篇】AutoResetEvent和ManualResetEvent的区别(中级)

    引入命名空间: using System.Threading; AutoResetEvent: autoResetEvent.WaitOne();//运行完后,**自动将事件...ManualResetEvent: manulResetEvent.WaitOne();//运行完后,**不会自动将事件状态设置为无信号**

    AutoResetEvent_Examples.zip_AutoResetEvent_ManualResetEvent

    线程事例代码,ManualResetEvent,AutoResetEvent

    详细解析C#多线程同步事件及等待句柄

    最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也简要提了一下System.Threading....

    python实现AutoResetEvent类的阻塞模式方法解析

    搞过C#多线程的人对其中的AutoResetEvent和ManualResetEvent这两个类都理解,其中的WaitOne()方法和Set()以及Reset()方法在线程同步当中用的是比较多的。 AutoResetEvent :当某个线程执行到WaitOne()方法时,该线程...

    多线程实验_1

    C#多线程实验,就AutoResetEvent,ManualResetEvent,Thread.join(),委托多线程回调。

    NET多线程同步方法详解

    1) 互斥(Mutex), 信号量(Semaphore), 事件(AutoResetEvent/ManualResetEvent)2) 线程池 除了以上的这些对象之外实现线程同步的还可以使用Thread.Join方法。这种方法比较简单,当你在第一个线程运行时想等待第二个...

    深入多线程之:Wait与Pulse的使用详解

    Monitor借助它的静态方法Wait,Pulse,PulseAll提供了一个更给力的信号构造,使用这些方法和lock语句,你可以自己实现AutoResetEvent,ManualResetEvent和Semaphore。甚至WaitHandle的WaitAll和WaitAny方法了。怎样...

    C# 多线程同步与互斥,使用Mutex和AutoResetEvent类

    C# 使用Mutex和AutoResetEvent类处理多线程同步与互斥,调试并完善了网上文档的代码。经测试能很好地实现要求,但还有一些地方不是特别明白,都写在注释中了,请高手给予指点。

    C#实现多线程的同步方法实例分析

    本文主要描述在C#中线程同步的方法。线程的基本概念网上资料也很多就不再赘述了。直接接入 主题,在多线程开发的应用...1) 互斥(Mutex), 信号量(Semaphore), 事件(AutoResetEvent/ManualResetEvent) 2) 线程池 除了以上

    C#实现多线程的同步方法详解

    本文主要描述在C#中线程同步的方法。线程的基本概念网上资料也很多就不再...系统内核对象1)互斥(Mutex),信号量(Semaphore),事件(AutoResetEvent/ManualResetEvent)2)线程池除了以上的这些对象之外实现线程同步的还可

    C#多线程编程中的锁系统(三)

    主要介绍了C#多线程编程中的锁系统(三),本本文主要说下基于内核模式构造的线程同步方式、事件、信号量以及WaitHandle、AutoResetEvent、ManualResetEvent等内容,需要的朋友可以参考下

    C#多线程面面观(博客源码)

    5.线程间通信WaitHandle、ManualResetEvent、AutoResetEvent和Barrier;6.任务Task、TaskFactory和Parallel;7.异步委托;8.其他,UI多线程,Timer等;博客地址:...

    prex:ES6 Promise之上的异步协调原语和扩展

    类:ManualResetEvent 类:AutoResetEvent 类别:信号量 类:CountdownEvent 类别:屏障 类:ReaderWriterLock 接口:LockHandle 界面:UpgradeableLockHandle 类别:递延 排程 类:AsyncQueue 类:...

    深入多线程之:用Wait与Pulse模拟一些同步构造的应用详解

    你可能在上篇文章中《深入多线程之:双向信号与竞赛的用法分析》注意到了这个模式:两个Waiting 循环都要下面的构造: 代码如下: ...让我们使用Wait和Pulse来为ManualResetEvent完成剩余的代码吧。 代码如下:r

    threadDemo.rar

    包含:线程的创建方式、排它锁(lock、Mutex、SpinLock)、非排它锁(ReaderWriterLockSlim、SemaphoreSlim)、使用事件等待句柄发送信号(发送信号ManualResetEvent、发送信号AutoResetEvent、发送信号...

    threading in C# - C#线程

    AutoResetEvent................................................................................................................ 26 ManualResetEvent .......................................................

Global site tag (gtag.js) - Google Analytics