网上有很多AutoResetEvent和ManualResetEvent的详细介绍,在这里不做过多详细的解释,写下自己的一点心得留作备忘。

AutoResetEvent和ManualResetEvent都是事件锁,事件的功能就是可以在被监控者发生某种变化后立即通知监控者并做出相应反应。

在使用多线程过程中,锁几乎是不可缺少的一项,我们拿信号量和事件锁举例来说。

如果有一个厨师和一群顾客,如果是使用信号量的话,情况如下:顾客询问厨师:“饭做好了吗?”,厨师:“还没有好,等一会吧!”,顾客继续等待一段时间后继续询问,循环往复,直到饭做好后开始吃饭。

如果采用事件锁的话,情况如下:厨师告诉顾客:“你先等一会吧,饭做好后,我告诉你!”,顾客等待,厨师告诉顾客:“饭做好了,你过来吃吧!”,顾客吃饭。在这种模式下,使用事件锁就会好一些。

AutoResetEvent myAutoRetEvent = new AutoResetEvent(false);

ManualResetEvent myManualRetEvent = new ManualResetEvent(false);

//通知正在等待的线程已发生事件(厨师)

//构造函数函数变量如果为:false,初始状态非终止状态。厨师的初始状态就很忙碌,顾客如果要吃饭就要等待。

//构造函数变量如果为:true,初始状态为终止状态。厨师的初始状态为已经做好了饭,顾客可以直接吃饭。

/// <summary>
/// 通知正在等待的线程已发生事件 true:初始状态为终止状态 false:初始状态为非终止状态
/// 目前的初始状态未厨师没有做饭
/// </summary>
private AutoResetEvent myAutoRetEvent = new AutoResetEvent(false); private void button2_Click(object sender, EventArgs e)
{
Thread myThread = new Thread(new ThreadStart(RunStart));
myThread.Start();
//厨师做饭做了3000ms
Thread.Sleep();
//厨师告诉顾客饭做好了
myAutoRetEvent.Set();
} private void RunStart()
{
//顾客来了,要吃饭
myAutoRetEvent.WaitOne();
MessageBox.Show("吃饭...");
}

单击按钮后,等待3秒后,弹出“吃饭...”,如果把构造函数中的false改为true,单击按钮后,立即弹出“吃饭...”。

而ManualResetEvent与AutoResetEvent的区别是:前者(厨师做好饭后,所有的顾客都开始吃饭),而后者(厨师做好饭后,只有一个顾客能吃到饭。)

AutoResetEvent:

/// <summary>
/// 通知正在等待的线程已发生事件 true:初始状态为终止状态 false:初始状态为非终止状态
/// 目前的初始状态未厨师没有做饭
/// </summary>
private AutoResetEvent myAutoRetEvent = new AutoResetEvent(false); private void button3_Click(object sender, EventArgs e)
{
//来了一个顾客1
Thread myThread1 = new Thread(new ThreadStart(Run_1));
myThread1.Start();
//来了一个顾客2
Thread myThread2 = new Thread(new ThreadStart(Run_2));
myThread2.Start(); //厨师做饭做3000ms
Thread.Sleep();
//厨师做好饭了,通知看谁能吃上饭
myAutoRetEvent.Set();
} private void Run_1()
{
//顾客1过来了,要吃饭,等厨师做好饭
myAutoRetEvent.WaitOne();
MessageBox.Show("我是顾客1开始吃饭...");
} private void Run_2()
{
//顾客2过来了,要吃饭,等厨师做好饭
myAutoRetEvent.WaitOne();
MessageBox.Show("我是顾客2开始吃饭...");
}

ManualResetEvent:

private ManualResetEvent myManualRetEvent = new ManualResetEvent(false);

        private void button4_Click(object sender, EventArgs e)
{
//来了一个顾客1
Thread myThread3 = new Thread(new ThreadStart(Run_3));
myThread3.Start();
//来了一个顾客2
Thread myThread4 = new Thread(new ThreadStart(Run_4));
myThread4.Start(); //厨师做饭做3000ms
Thread.Sleep();
//厨师做好饭了,通知看谁能吃上饭
myManualRetEvent.Set();
} private void Run_3()
{
//顾客1过来了,要吃饭,等厨师做好饭
myManualRetEvent.WaitOne();
MessageBox.Show("我是顾客1开始吃饭...");
} private void Run_4()
{
//顾客2过来了,要吃饭,等厨师做好饭
myManualRetEvent.WaitOne();
MessageBox.Show("我是顾客2开始吃饭...");
}

厨师做好饭后,通知大家,所有等待的顾客都开始吃饭。两者的区别如上所述。

此篇文章是受csdn 陆敏技的文章启发,便于自己的理解记忆。

c# AutoResetEvent和ManualResetEvent的更多相关文章

  1. C#多线程同步事件及等待句柄AutoResetEvent 和 ManualResetEvent

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

  2. 多线程间通信之AutoResetEvent和ManualResetEvent的原理分析

    AutoResetEvent 允许线程通过发信号互相通信. 通常,当线程需要独占访问资源时使用该类. 线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号. 如果 AutoRe ...

  3. 个人对AutoResetEvent和ManualResetEvent的理解(转载)

    仅个人见解,不对之处请指正,谢谢. 一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方 ...

  4. AutoResetEvent和ManualResetEvent理解 z

    AutoResetEvent和ManualResetEvent用于多线程之间代码执行顺序的控制,它们继承自WaitHandle,API相同,但在使用中还是有区别的. 每次使用时虽然理解了,但由于没有去 ...

  5. C#AutoResetEvent和ManualResetEvent的区别

    一:终止状态和非终止状态 首先说说线程的终止状态和非终止状态.AutoResetEvent和ManualResetEvent的构造函数中,都有bool变量来指明线程的终止状态和非终止状态.true表示 ...

  6. 线程同步(AutoResetEvent与ManualResetEvent)

    前言 在我们编写多线程程序时,会遇到这样一个问题:在一个线程处理的过程中,需要等待另一个线程处理的结果才能继续往下执行.比如:有两个线程,一个用来接收Socket数据,另一个用来处理Socket数据, ...

  7. AutoResetEvent与ManualResetEvent区别

    本文来自:http://www.360doc.com/content/10/1126/10/3267996_72536817.shtml 在.Net多线程编程中,AutoResetEvent和Manu ...

  8. WaitHandle、AutoResetEvent、ManualResetEvent

    多线程中的锁系统(三)-WaitHandle.AutoResetEvent.ManualResetEvent 介绍 本章主要说下基于内核模式构造的线程同步方式,事件,信号量. 目录 一:理论 二:Wa ...

  9. 对比AutoResetEvent和ManualResetEvent

    ManualResetEvent和AutoResetEvent 比较 ManualResetEvent和AutoResetEvent都继承自EventWaitHandler,它们的唯一区别就在于父类 ...

随机推荐

  1. PKU 1276 Cash Machine

    <span style="color:#000099;">/* Cash Machine Time Limit: 1000MS Memory Limit: 10000K ...

  2. APlayer组件自制播放器

    .NET中使用APlayer组件自制播放器 2015-02-02 09:46 by xiaozhi_5638, 402 阅读, 9 评论, 收藏, 编辑 目录 说明 APlayer介绍 APlayer ...

  3. PHP单元测试利器:PHPUNIT初探

    开始动手安装phpunit 本文中将通过介绍php中的单元测试利器phpunit(http://phpunit.de/),并通过实际例子来讲解如何在实际工作中运用phpunit.首先安装phpunit ...

  4. 使用Scala操作Mongodb

    介绍 Scala是一种功能性面向对象语言.它融汇了很多前所未有的特性.而同一时候又执行于JVM之上.随着开发人员对Scala的兴趣日增,以及越来越多的工具支持,无疑Scala语言将成为你手上一件不可缺 ...

  5. 基于Quqrtz.NET 做的任务调度管理工具

    基于Quqrtz.NET 做的任务调度管理工具 国庆前,需求让我看了一下任务调度的数据表设计.和之前一样,有100多个字段,p1 ~ p100, 我说这是干嘛啊!按这写,写死去了! 然后在网上搜了一下 ...

  6. jQuery弹出窗口完整代码

    jQuery弹出窗口完整代码 效果体验:http://keleyi.com/keleyi/phtml/jqtexiao/1.htm 1 <!DOCTYPE html PUBLIC "- ...

  7. 我的Android 4 学习系列之使用 Internet 资源

    目录 连接Internet资源 分析XML资源 使用Download Manager下载文件 查询Download manager 使用Account Manager 对 Google App Eng ...

  8. 一些小bug

    1.ie6-ie8中是不支持的,需要加上下面这句话: filter: progid:DXImageTransform.Microsoft.Alpha(opacity=70);   2.去除虚线框 a  ...

  9. 查询职责分离(CQRS)模式

    查询职责分离(CQRS)模式 在常用的三层架构中,通常都是通过数据访问层来修改或者查询数据,一般修改和查询使用的是相同的实体.在一些业务逻辑简单的系统中可能没有什么问题,但是随着系统逻辑变得复杂,用户 ...

  10. Android项目---LayoutParams

    LinearLayout.LayoutParams extends ViewGroup.MarginLayoutParams java.lang.Object    ↳ android.view.Vi ...