当在C#使用多线程时就免不了使用AutoResetEvent和ManualResetEvent类,可以理解这两个类可以通过设置信号来让线程停下来或让线程重新启动,其实与操作系统里的信号量很相似(汗,考完考试已经有点忘记了)。下面上代码

class Program
{
const int count = ;
//赋值为false也就是没有信号
static AutoResetEvent myResetEvent = new AutoResetEvent(false);
static int number;
static void Main(string[] args)
{
Thread thread = new Thread(funThread);
thread.Name = "QQ";
thread.Start();
for (int i = ; i < count; i++)
{
Console.WriteLine("first number: {0}",i);
number = i;
//这里是设置为有信号
myResetEvent.Set();
Thread.Sleep();
}
thread.Abort();
} static void funThread()
{
while (true)
{
//执行到这个地方时,会等待set调用后改变了信号才接着执行
myResetEvent.WaitOne();
Console.WriteLine("end {0} number: {1}", Thread.CurrentThread.Name, number);
}
} }

输出结果为

first number:1

end QQ number:1

first number:2

end QQ number:3

.....

简单来说只有调用Set()方法后才能执行WaitOne()后面的代码,AutoResetEvent和ManualResetEvent分别都有Set()改变为有信号 ,Reset()改变为无信号,WaitOne()将会阻塞当前调用的线程,直到有信号为止,即执行了Set()方法,WaitOne()方法还可以带指定时间的参数。

理解了AutoResetEvent后再理解ManualResetEvent也就不难了,AutoResetEvent与ManualResetEvent的区别是,AutoResetEvent.WaitOne()会自动改变事件对象的状态,即AutoResetEvent.WaitOne()每执行一次,事件的状态就改变一次,也就是从有信号变为无信号。而ManualResetEvent则是调用Set()方法后其信号量不会自动改变,除非再设置Reset()方法。

在.Net多线程编程中,AutoResetEvent和ManualResetEvent这两个类经常用到, 他们的用法很类似,但也有区别。Set方法将信号置为发送状态,Reset方法将信号置为不发送状态,WaitOne等待信号的发送。可以通过构造函数的参数值来决定其初始状态,若为true则非阻塞状态,为false为阻塞状态。如果某个线程调用WaitOne方法,则当信号处于发送状态时,该线程会得到信号, 继续向下执行。其区别就在调用后,AutoResetEvent.WaitOne()每次只允许一个线程进入,当某个线程得到信号后,AutoResetEvent会自动又将信号置为不发送状态,则其他调用WaitOne的线程只有继续等待.也就是说,AutoResetEvent一次只唤醒一个线程;而ManualResetEvent则可以唤醒多个线程,因为当某个线程调用了ManualResetEvent.Set()方法后,其他调用WaitOne的线程获得信号得以继续执行,而ManualResetEvent不会自动将信号置为不发送。也就是说,除非手工调用了ManualResetEvent.Reset()方法,则ManualResetEvent将一直保持有信号状态,ManualResetEvent也就可以同时唤醒多个线程继续执行。

上述理论部分理解了,请看下面代码,和上边代码输出结果是一致的:

class Program
{
const int count = ;
//赋值为false也就是没有信号
static ManualResetEvent myResetEvent = new ManualResetEvent(false);
static int number;
static void Main(string[] args)
{
Thread thread = new Thread(funThread);
thread.Name = "QQ";
thread.Start();
for (int i = ; i < count; i++)
{
Console.WriteLine("first number: {0}", i);
number = i;
//这里是设置为有信号
myResetEvent.Set();
Thread.Sleep();
}
thread.Abort();
Console.ReadKey();
} static void funThread()
{
while (true)
{
//执行到这个地方时,会等待set调用后改变了信号才接着执行
myResetEvent.WaitOne();
Console.WriteLine("end {0} number: {1}", Thread.CurrentThread.Name, number);
myResetEvent.Reset();//#此处取消信号 注意
}
} }

看懂了这两处代码,相比就会了解二者的区别了!

C#深入理解AutoResetEvent和ManualResetEvent的更多相关文章

  1. C#理解AutoResetEvent和ManualResetEvent

    当在C#使用多线程时就免不了使用AutoResetEvent和ManualResetEvent类,可以理解这两个类可以通过设置信号来让线程停下来或让线程重新启动,其实与操作系统里的信号量很相似(汗,考 ...

  2. C# 定时器和队列结合,卖包子啦,Timer、 AutoResetEvent、 ManualResetEvent

    再你们得到源码之前,我先做个广告:张家港杰德机械/张家港三兴华轩机械是我一朋友的公司,希望需要做净水,灌装机,拔盖机,封口机,传送带等的朋友光顾. 张家港杰德机械有限公司:http://www.jie ...

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

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

  4. AutoResetEvent和ManualResetEvent理解 z

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

  5. AutoResetEvent和ManualResetEvent理解

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

  6. 个人对AutoResetEvent和ManualResetEvent的理解

    一.作用 AutoResetEvent和ManualResetEvent可用于控制线程暂停或继续,拥有重要的三个方法:WaitOne.Set和Reset. 这三个方法的官方定义并不好理解,什么终止.非 ...

  7. [转]个人对AutoResetEvent和ManualResetEvent的理解

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

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

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

  9. C#AutoResetEvent和ManualResetEvent的区别

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

随机推荐

  1. synchronized的锁问题

    有一个类A,提供了三个方法.分别是静态同步方法,非静态同步方法,含有静态代码块的方法 1 class A{ 2 public static synchronized void print1(){ 3 ...

  2. lombok的简单介绍(1)

    一.项目背景 在写Java程序的时候经常会遇到如下情形: 新建了一个Class类,然后在其中设置了几个字段,最后还需要花费很多时间来建立getter和setter方法 lombok项目的产生就是为了省 ...

  3. MySQL复制ERROR 1794 (HY000): Slave is not configured or failed to initialize properly.

    ERROR 1794 (HY000): Slave is not configured or failed to initialize properly. You must at least set  ...

  4. 【爬坑】DataNode 无法正常启动解决方案

    0. 说明 DataNode 无法正常启动的原因 & 解决方案 1. 原因一 在 start-all.sh 之后 DataNode 无法正常启动,单独启动也启动不了 可能的原因 多次格式化,导 ...

  5. CentOS7安装搭建.Net Core 2.0环境-详细步骤

    一.构建.Net core 2的应用程web发布 因为是用来测试centos上的core 环境,先直接用vs17自带的core实例. 二.部署CentOS7的core环境 1.连接并启动之前安装的虚拟 ...

  6. vue_表单控件

    Vue.js中提供 v-model 的指令对表单元素进行双向数据绑定,在修改表单元素值的同时,实例 vm 中对应的属性值也同时更新,反之亦然.本小节介绍主要input元素绑定v-model 后的具体用 ...

  7. Activity声明周期1

    oncreate():在Activity对象第一次创建时调用 onStart():当Activity变得可见时调用该函数 onResume():当Activity开始准备于用户交互时调用该方法(即获得 ...

  8. 【九校3D2T3】世界第一的猛汉王

    [问题描述] 卡普地公司举办了「世界第一的猛汉王」全球大会,来自世界各地的猛汉为了争夺「猛汉王」的名号前来一决高下.现在举行的是弓箭组选拔赛.卡普地公司为比赛新建了一张PVP地图——「猛汉竞技场」.有 ...

  9. 月球美容计划之最小生成树(MST)

    寒假学的两个算法,普里姆,克鲁斯卡尔最终弄明确了.能够发总结了 先说说普里姆,它的本质就是贪心.先从随意一个点開始,找到最短边,然后不断更新更新len数组,然后再选取最短边并标记经过的点,直到全部的点 ...

  10. Hadoop 基本概念

    一.Hadoop 简介 Hadoop 是一个由 Apache 基金会所开发的分布式系统基础架构,它可以使用户在不了解分布式底层细节的情況下开发分布式程序,充分利用集群的威力进行高速运算和存储. 从其定 ...