`
weizhai12
  • 浏览: 149341 次
  • 性别: 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

    在多线程编程中,`AutoResetEvent` 和 `ManualResetEvent` 是两种重要的同步原语,用于控制线程间的协作和同步。本压缩包文件提供了关于这两种事件类型的实例代码,帮助开发者理解它们的工作原理和用法。 首先,让...

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

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

    线程间通信与同步控制1

    AutoResetEvent和ManualResetEvent是事件对象,用于线程间的通信和同步,其中AutoResetEvent在释放一个等待线程后自动重置,而ManualResetEvent则需要手动重置。 在设计多线程程序时,应当避免使用Thread.Abort来...

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

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

    c# 线程同步: 详解lock,monitor,同步事件和等待句柄以及mutex

    例如,AutoResetEvent和ManualResetEvent分别用于单次信号和多次信号。这些事件可以与其他同步机制结合使用,以实现复杂的同步策略。 等待句柄是Windows操作系统级别的同步机制,如Mutex、Semaphore和Event。Mutex...

    五个多线程同步应用小程序

    有两类EventWaitHandle:AutoResetEvent和ManualResetEvent。AutoResetEvent在事件触发后自动重置,只有一个等待的线程可以继续执行;而ManualResetEvent则需要手动调用Reset() 方法来重置事件状态,因此可以唤醒多...

    归纳一下C#线程同步的几种方法.docx

    6. **EventWaitHandle、AutoResetEvent 和 ManualResetEvent**: 这些事件类用于线程间的通信,线程等待事件触发后才能继续执行。`AutoResetEvent`在一个信号后自动重置,而`ManualResetEvent`需要手动重置。 7. *...

    多线程小结

    ##### AutoResetEvent 和 ManualResetEvent 这两种类提供了基于事件的等待机制,允许一个或多个线程等待某个事件的发生。 ```csharp AutoResetEvent autoEvent = new AutoResetEvent(false); void WaitMethod() {...

    使用WaitHandle 内含C#编写源代码

    6. **AutoResetEvent和ManualResetEvent**:这两个是`EventWaitHandle`的子类,用于创建事件。`AutoResetEvent`在释放后自动重置,只允许一个线程通过;`ManualResetEvent`则需要手动重置,可以允许多个线程通过。 ...

    C# 多线程总结

    包括AutoResetEvent和ManualResetEvent,用于线程间的信号通信。 2.5.1 AutoResetEvent ```csharp AutoResetEvent autoEvent = new AutoResetEvent(false); autoEvent.Set(); // 释放信号 autoEvent.WaitOne(); //...

    微软官方教程:.NET Windows编程系列课程(15):多线程编程

    - AutoResetEvent和ManualResetEvent是线程同步事件,可以用来让一个线程等待另一个线程完成某个操作。 - WaitHandle类的WaitOne()方法用于线程等待,Signal()方法用于唤醒等待的线程。 6. **异步编程模型**: -...

    多线程采集C#源代码

    例如,AutoResetEvent和ManualResetEvent可作为线程间等待和通知的信号。 6. **线程状态与优先级**:每个线程都有自己的生命周期和状态(如新建、运行、等待、停止等)。Thread类提供了属性和方法来获取或设置线程...

    线程学习源码

    EventWaitHandle类提供了一种线程间的通信方式,如AutoResetEvent和ManualResetEvent,它们可以用来控制线程何时继续执行。WaitOne方法使线程等待事件发生,Set方法则释放等待的线程。 十、线程挂起与恢复 Thread类...

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

    在本篇文章中,我们将探讨基于内核模式构造的线程同步方式,包括事件、信号量,以及WaitHandle、AutoResetEvent和ManualResetEvent这三种重要的同步工具。 一、理论 线程同步可以分为用户模式构造和内核模式构造。...

    ManualResetEvent继续等待.rar

    与AutoResetEvent的区别在于,ManualResetEvent在释放一次后不会自动重置,需要开发者手动调用Reset方法来恢复到未设置状态。 **初始化ManualResetEvent** ManualResetEvent的构造函数允许我们初始化其初始状态。...

    C#线程同步ManualResetEvent

    与`AutoResetEvent`不同,`ManualResetEvent`在释放一次后不会自动重置,需要手动调用`Reset()`方法来恢复未启动状态。 **一、构造函数** `ManualResetEvent`有两个构造函数: 1. `ManualResetEvent(false)`:初始...

    多线程与网络编程

    本文将重点解析多线程中的线程同步机制,特别是`AutoResetEvent`和`ManualResetEvent`这两种关键同步对象的特性和使用场景。 #### 终止状态与非终止状态:理解线程的生命周期 在多线程编程中,线程的生命周期至关...

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

    Mutex(互斥锁)和AutoResetEvent(自动重置事件)是.NET框架提供的两种工具,用于解决这些问题。 Mutex是一种全局资源锁,它允许在任何时间只有一个线程访问特定的资源或代码段。在C#中,我们可以使用Mutex的构造...

    C# 多线程同步、异步_AutoResetEvent用法

    3. **手动重置**:与`ManualResetEvent`不同,`AutoResetEvent`只允许一个线程通过,如果需要多次触发,需要再次调用`Set()`方法。 ### 四、AutoResetEvent的使用 在C#中,我们可以这样使用`AutoResetEvent`: ``...

Global site tag (gtag.js) - Google Analytics