区别与示例

AutoResetEvent 和 ManualResetEvent 十分相似。两者之间的区别,在于前者是自动(Auto),后者是手动(Manua)。

你可以先运行下面的示例,再测试两者的区别。

AutoResetEvent 示例:

    class Program
{
// 线程通知
private static AutoResetEvent resetEvent = new AutoResetEvent(false); static void Main(string[] args)
{
// 创建线程
new Thread(DoOne).Start(); // 用于不断向另一个线程发送信号
while (true)
{
Console.ReadKey();
resetEvent.Set(); // 发生通知,设置终止状态
}
} public static void DoOne()
{
Console.WriteLine("① 等待中,请发出信号允许我运行");
resetEvent.WaitOne(); Console.WriteLine("② 等待中,请发出信号允许我运行"); resetEvent.WaitOne();
Console.WriteLine("③ 等待中,请发出信号允许我运行"); // ... Console.WriteLine("线程结束");
}
}

ManualResetEvent 类示例:

    class Program
{
private static ManualResetEvent resetEvent = new ManualResetEvent(false);
static void Main(string[] args)
{
new Thread(DoOne).Start();
// 用于不断向另一个线程发送信号
while (true)
{
Console.ReadKey();
resetEvent.Set(); // 发生通知,设置终止状态
}
} public static void DoOne()
{
Console.WriteLine("等待中,请发出信号允许我运行");
resetEvent.WaitOne(); // 后面的都无效,线程会直接跳过而无需等待
resetEvent.WaitOne();
resetEvent.WaitOne();
resetEvent.WaitOne();
resetEvent.WaitOne();
resetEvent.WaitOne();
Console.WriteLine("线程结束");
}
}

因为 AutoResetEvent 对象在 .WaitOne() 方法等待信号完毕后,会自动重置为非终止状态,相当于高速收费站自动闸门,一辆车过去后,机器自动关闸。

ManualResetEvent 相当于人工闸门,打开后编写人工关闭闸门,不然的话闸门会一直处于打开状态。

ManualResetEvent 主要用于更加灵活的线程信号传递场景。

ManualResetEvent 类

表示线程同步事件,收到信号时,要想下一次依然生效,必须手动重置该事件。

因为 ManualResetEvent 类跟 AutoManualResetEvent 类十分接近,这里就不赘述了。

它们的使用区别主要是:

AutoResetEvent 类,每次 Set() ,跳过一个 WaitOne()。因为会 自动恢复设置,所以下次碰到 WaitOne() 会继续等待。

ManualResetEvent 类, Set() 后,不会重置设置,因此一旦使用了 Set() 后,就会一路放通,不会再等待。

其构造函数如下:

构造函数 说明
ManualResetEvent(Boolean) 用一个指示是否将初始状态设置为终止的布尔值初始化 ManualResetEvent 类的新实例。

其常用方法如下:

方法 说明
Close() 释放由当前 WaitHandle 占用的所有资源。
Reset() 将事件状态设置为非终止,从而导致线程受阻。
Set() 将事件状态设置为有信号,从而允许一个或多个等待线程继续执行。
WaitOne() 阻止当前线程,直到当前 WaitHandle 收到信号。
WaitOne(Int32) 阻止当前线程,直到当前 WaitHandle 收到信号,同时使用 32 位带符号整数指定时间间隔(以毫秒为单位)。
WaitOne(Int32, Boolean) 阻止当前线程,直到当前的 WaitHandle 收到信号为止,同时使用 32 位带符号整数指定时间间隔,并指定是否在等待之前退出同步域。
WaitOne(TimeSpan) 阻止当前线程,直到当前实例收到信号,同时使用 TimeSpan 指定时间间隔。
WaitOne(TimeSpan, Boolean) 阻止当前线程,直到当前实例收到信号为止,同时使用 TimeSpan 指定时间间隔,并指定是否在等待之前退出同步域。

ManualResetEventSlim

ManualResetEventSlim 相对 ManualResetEvent ,当等待时间预计非常短并且事件不跨越进程边界时,可以使用此类来获得比 ManualResetEvent 更好的性能。

从代码使用来看,没有啥区别,主要就是考虑性能下时,两者不同场景。

这里就不对这两个类型赘述了。

C#多线程(7):手动线程通知的更多相关文章

  1. C#多线程(6):线程通知

    目录 AutoRestEvent 类 常用方法 一个简单的示例 解释一下 复杂一点的示例 解释 回顾一下,前面 lock.Monitor 部分我们学习了线程锁,Mutex 部分学习了进程同步,Sema ...

  2. 20190102(多线程,守护线程,线程互斥锁,信号量,JoinableQueue)

    多线程 多进程: 核心是多道技术,本质上就是切换加保存技术. 当进程IO操作较多,可以提高程序效率. 每个进程都默认有一条主线程. 多线程: 程序的执行线路,相当于一条流水线,其包含了程序的具体执行步 ...

  3. .NET面试题解析(07)-多线程编程与线程同步

      系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实是很多的,比如多线程编程.线程上下文.异步编程.线程同步构造.GUI的跨线程访问等等, ...

  4. .NET面试题解析(07)-多线程编程与线程同步 (转)

    http://www.cnblogs.com/anding/p/5301754.html 系列文章目录地址: .NET面试题解析(00)-开篇来谈谈面试 & 系列文章索引 关于线程的知识点其实 ...

  5. C#学习笔记之线程 - 通知Signal

    通知事件等待句柄 Signal With EventWaitHandle 事件等待句柄常用于通知.当一个线程等待直到接收到另外一个线程发出的信号.事件等待句柄是最简单的信号结构,它与C#事件无关.有三 ...

  6. VC中利用多线程技术实现线程之间的通信

    当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软 ...

  7. -1-5 java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁 sleep()和wait()方法的区别 为什么wait(),notify(),notifyAll()等方法都定义在Object类中

     本文关键词: java 多线程 概念 进程 线程区别联系 java创建线程方式 线程组 线程池概念 线程安全 同步 同步代码块 Lock锁  sleep()和wait()方法的区别 为什么wait( ...

  8. Python中的多线程编程,线程安全与锁(二)

    在我的上篇博文Python中的多线程编程,线程安全与锁(一)中,我们熟悉了多线程编程与线程安全相关重要概念, Threading.Lock实现互斥锁的简单示例,两种死锁(迭代死锁和互相等待死锁)情况及 ...

  9. 转:java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例

    java多线程CountDownLatch及线程池ThreadPoolExecutor/ExecutorService使用示例 1.CountDownLatch:一个同步工具类,它允许一个或多个线程一 ...

  10. Java多线程并发02——线程的生命周期与常用方法,你都掌握了吗

    在上一章,为大家介绍了线程的一些基础知识,线程的创建与终止.本期将为各位带来线程的生命周期与常用方法.关注我的公众号「Java面典」了解更多 Java 相关知识点. 线程生命周期 一个线程不是被创建了 ...

随机推荐

  1. 买彩票能中大奖?用Java盘点常见的概率悖论 | 京东云技术团队

    引言 <双色球头奖概率与被雷劈中的概率哪个高?> <3人轮流射击,枪法最差的反而更容易活下来?> 让我们用Java来探索ta们! 悖论1:著名的三门问题 规则描述:你正在参加一 ...

  2. SPI在Java中的实现与应用 | 京东物流技术团队

    1 SPI的概念 API API在我们日常开发工作中是比较直观可以看到的,比如在 Spring 项目中,我们通常习惯在写 service 层代码前,添加一个接口层,对于 service 的调用一般也都 ...

  3. 2024-01-27:用go语言,阿里巴巴走进了装满宝藏的藏宝洞。藏宝洞里面有N堆金币, 第i堆金币的总重量和总价值分别是m[i]、v[i], 阿里巴巴有一个承重量为T的背包,但并不一定有办法将全部的

    2024-01-27:用go语言,阿里巴巴走进了装满宝藏的藏宝洞.藏宝洞里面有N堆金币, 第i堆金币的总重量和总价值分别是m[i].v[i], 阿里巴巴有一个承重量为T的背包,但并不一定有办法将全部的 ...

  4. C# await和Result对比

    1.Result 上图是微软官网的截图,由图可知在使用GetXXXX的方法的时候,会阻塞调用其他线程,直到当前异步操作完成,相当于调用wait方法.但是使用异步编程应该避免使用TASK.WAIT或TA ...

  5. 字节码编程,Javassist篇五《使用Bytecode指令码生成含有自定义注解的类和方法》

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 到本章为止已经写了四篇关于字节码编程的内容,涉及了大部分的API方法.整体来说对 J ...

  6. list集合去重_谈谈Java中Set集合去重的原理

    导读:Java中Set接口是Collectio的子接口,Set集合不允许包含相同的元素.如果添加相同的元素, add()会返回FALSE, 新元素不会加入.Set集合常用于元素为数字.字符串去重等,但 ...

  7. 《ASP.NET Core 微服务实战》-- 读书笔记(第5章)

    第 5 章 创建数据服务 选择一种数据存储 由于我坚持要尽可能的跨平台,所以我决定选用 Postgres,而不用 SQL Server 以照顾 Linux 或 Mac 电脑的读者 构建 Postgre ...

  8. 2023年多校联训NOIP层测试2

    2023年多校联训NOIP层测试2 爆零了 T1 HDU 4786 Fibonacci Tree \(0pts\) @wangyunbiao: 不可以,总司令 我:不,可以,总司令 @wangyunb ...

  9. 反悔贪心&模拟费用流

    贪心是一种常用的算法,它能够获得局部最优解,但我们往往需要的是全局最优解,所以我们在贪心的时候加入和反悔的机制,让他能够得到全局最优解. 由于网络流中的退流操作本质上也是反悔贪心,所以在实现反悔贪心时 ...

  10. NC20189 [JSOI2011]分特产

    题目链接 题目 题目描述 JYY 带队参加了若干场ACM/ICPC 比赛,带回了许多土特产,要分给实验室的同学们. JYY 想知道,把这些特产分给N 个同学,一共有多少种不同的分法? 当然,JYY 不 ...