C#中使用AutoResetEvent或者ManualResetEvent做线程管理

news/2024/10/2 1:21:20

1. Task/thread/sync/async..await/WhenAll
相关基础知识参见此处链接

2. 什么是AutoResetEvent和ManualResetEvent事件

  • 他们都是C#中System.Threading下面的类。用于在多个线程之间进行事件通知和管理。
  • 他们的管理方法主要是三个:
    • Reset():关闭
    • WaitOne():阻挡
    • Set():启动
  • AutoResetEvent和ManualResetEvent的区别
    • 自动方法遵循set -> WaitOne -> Reset的流程自动执行,但是自动方法的一个set只能控制一个线程
    • 手动方法也是遵循set -> WaitOne -> Reset的流程,但是手动方法可以灵活的进行手动控制,一个手动的set可以控制多个同步线程。

3. 理解

  • 不管是auto还是manual,都要经历的步骤如下(其他地方看到一个很形象的举例):
车辆过高速收费站时:
自动:车闸默认关闭(new AutoResetEvent(false)) -> 车辆到达收费站被阻(waitone()) -> 交费,然后开闸(set()) -> 关闭车闸(reset())手动:车闸打开后(set()),并不会自动关闭,所以如果不去手动关闭(reset()),后面的车会一辆一辆的通过。自动可以自动关闭车闸(reset()),让一次只能过一个车,特点就是自动情况下,同步存在两个同步线程,最终只能执行第一个线程。
手动需要手动关闭车闸(reset()),特点就是手动情况下,如果不手动reset(),所有线程都会被依次执行完毕。
WaitOne()是否生效取决于有没有Reset()。如果一开始就是Reset()的,那么WaitOne不会阻挡任何线程执行。

4. AutoResetEvent和ManualResetEvent的初始化状态

  • new Auto/ManualResetEvent(false):默认阻挡线程。
  • new Auto/ManualResetEvent(true):默认通过线程。
  • new Auto/ManualResetEvent(true)中,WaitOne没有任何意义,它阻挡不了线程

5. auto/manual测试代码

  • autoresetevent中的验证代码:
internal class Program
{static EventWaitHandle my_task1 = new AutoResetEvent(true);//默认自动执行static AutoResetEvent my_task2 = new AutoResetEvent(false);//默认自动阻挡//static ManualResetEvent my_task3 = new ManualResetEvent(false);//默认手动阻挡private static void Main(string[] args){//threadnew Thread(func1).Start();new Thread(func3).Start();my_task2.Set();//开启,因为func3的调用在func2的上面,所以set先管理到func3。func3能执行,func2不能执行,这表明autoresetevent是典型的队列操作形式new Thread(func2).Start();Console.ReadKey();}static void func1(){my_task1.WaitOne();Console.WriteLine("此时的waitOne不能阻挡线程执行");}static void func2(){my_task2.WaitOne();Console.WriteLine("此时的waitOne会阻挡线程执行");}static void func3(){my_task2.WaitOne();Console.WriteLine("此时的waitOne会阻挡线程执行,开启set后通过");}
}

输出结果:

  • manualresetevent中的验证代码
internal class Program
{//static EventWaitHandle my_task1 = new AutoResetEvent(true);//默认自动执行//static AutoResetEvent my_task2 = new AutoResetEvent(false);//默认自动阻挡static ManualResetEvent my_task3 = new ManualResetEvent(false);//默认手动阻挡private static void Main(string[] args){//threadnew Thread(func1).Start();new Thread(func2).Start();new Thread(func3).Start();my_task3.Set();//手动set一次,执行多个线程Timer my_time = new Timer(CloseDown,null,0,2000);//2秒计时器Console.ReadKey();}static void func1(){my_task3.WaitOne();Console.WriteLine("手动第一次执行");}static void func2(){my_task3.WaitOne();Console.WriteLine("手动第二次执行");}static void func3(){my_task3.WaitOne();Console.WriteLine("手动第三次执行");}static void func4(){Thread.Sleep(3000);//等待3秒,大于reset时间,故不会执行my_task3.WaitOne();Console.WriteLine("不会执行第四次");}/// <summary>/// 2秒后关闭线程/// </summary>/// <param name="o"></param>static void CloseDown(object o){ my_task3.Reset();}}

输出结果:

6. 总结

  • auto一次只能执行一个线程
  • manual开启后可以同步执行超多线程
  • AutoResetEvent.Set() = ManualResetEvent.Set() + ManualResetEvent.Reset();
  • 多个线程的暂停,继续,可以选择Manual。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/44899.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

ABC357

A link循环加每一个数,加到哪个数不能加了输出前一个数,注意如果加到最后还能加,记得输出\(n\)。点击查看代码 #include<bits/stdc++.h>using namespace std;int n,m; int h[105],sum;signed main(){cin >> n >> m;for(int i = 1;i <= n;++ i)cin >…

文献收获_2024.06.11

Pancreatic Tumor Segmentation as Anomaly Detection in CT Images Using Denoising Diffusion Models 来源:https://arxiv.org/pdf/2406.02653DDM做image translation实现胰腺分割 下面的是金标准Anomaly map 差值出来的Segmentation map 算dice系数,用于下游分类评价表格 …

极限网关助力好未来 Elasticsearch 容器化升级

极限网关在好未来的最佳实践案例,轻松扛住日增百 TB 数据的流量,助力 ES 从物理机到云原生架构的改造,实现了流控、请求分析、安全管理、无缝迁移等场景。一次完美的客户体验~背景 物理机架构时代 2022 年,好未来整个日志 Elasticsearch 拥有数十套服务集群,几百台物理机。…

dataGridView控件和contextMenuStrip控件的结合使用

效果展示: 0. 在dataGridView 控件中绑定 contextMenuStrip 控件, 设置 ContextMenuStrip1. 设置 dataGridView 选中类型为整行选中: SelectionMode: FullRowSelect不允许 dataGridView 一次能选择多个单元格: MultiSelect: Fale 2. 第二步再 dataGridView 控件中分别使用 Cel…

一款.NET开源、功能强大、跨平台的绘图库 - OxyPlot

前言 今天大姚给大家分享一款.NET开源(MIT License)、免费、跨平台、功能强大的绘图库,支持多平台使用(包括:WPF、UWP、WinForm、Silverlight、Xamarin.iOS、Xamarin.Android、Xamarin.Forms 和 Xamarin.Mac等):OxyPlot。项目源代码WindowsForms项目运行 VS打开OxyPlot.…

超好用mqtt服务器端server和客户端client协议通信学习测试工具

超好用mqtt服务器端server和客户端client协议通信学习测试工具作为物联网数据采集解决方案专业提供商,数采物联网小编daq-iot在这里做以下内容介绍,并诚挚的欢迎大家讨论和交流软件使用注意事项: 本软使用需要用户了解mqtt通信 参数设置好后,要先启动软件左下角的服务器端ser…

植浇

【IoT开发】onenet云平台+STM32的植物浇水系统的设计与实现 2024-1-16 16:58  237 1 1 分类: 物联网 文集: onenet摘要:由于城市居民工作忙,生活节奏快,人们经常忘记给植物浇水,为此设计一款基于STM32的植物浇水系统,主要由STM32单片机、土壤湿度传感器、温湿度传感…