这篇文章主要介绍了C#中ManualResetEvent 与 AutoResetEvent 区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
在多线程开发中,时常用到ManualResetEvent 与AutoResetEvent 。 它们如同道路交通中的信号灯。两者之间有什么区别呢?
共同点:
均继承EventWaitHandle 接口,因此,均具有以下功能:
Reset() //红灯
Set() //绿灯
WaitOne() // 等待信号
不同点:
AutoResetEvent 收到 Set 后 , 一次只能执行一个线程,其它线程继续 WaitOne 。
ManualResetEvent 收到 Set 后,所有处理 WaitOne 状态线程均继续执行。
msdn 提到(如果没有线程 处于WaitOne() 状态,而调用 Set ,AutoResetEvent将保持Set 状态):
调用Set信号AutoResetEvent释放等待线程。 AutoResetEvent 将保持终止状态直到一个等待线程释放,并自动返回到非信号状态。 如果没有线程处于等待状态,状态将无限期地保持已发出信号。
因此通常WatiOne 之前,先 Reset() 一下,清除Set 信号
需要注意的是(两个 Set 调用之间时间较短,第二个 Set 信号可能会丢失,因此连续 Set 调用,中间需要 Sleep 一定时间):
不能保证的每个调用Set方法将释放一个线程。 如果两次调用太靠近在一起,以便第二次调用前释放线程发生,只有一个线程被释放。 就像第二次调用未发生。 此外,如果Set时没有等待的线程调用和AutoResetEvent已终止,则调用不起作用。
有网友说:
AutoResetEvent.Set() = ManualResetEvent.Set() + ManualResetEvent.Reset();
个人理解 ,这只是原理层面含义,实际使用过程中,有差别的,如下示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace testManualResetEvent
{
class Program
{
static object objManualResetEvent = new object();
static System.Threading.ManualResetEvent manu = new System.Threading.ManualResetEvent(false);
//static System.Threading.AutoResetEvent manu = new System.Threading.AutoResetEvent(false);
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() => { Product(); }));
t.Start();
}
manu.Set();
manu.Reset();
Console.ReadKey();
}
static void Product()
{
manu.WaitOne(10000);
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
}
}
}
实际执行结果 , 在 执行 set 后 reset 前 ,有多少个线程唤起执行,无法预料:
需要加锁 ,确保一次通过一个线程:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace testManualResetEvent
{
class Program
{
static object objManualResetEvent = new object();
static System.Threading.ManualResetEvent manu = new System.Threading.ManualResetEvent(false);
//static System.Threading.AutoResetEvent manu = new System.Threading.AutoResetEvent(false);
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() => { Product(); }));
t.Start();
}
manu.Set();
//System.Threading.Thread.Sleep(100); //连续 set 需要 sleep
//manu.Set();
//manu.Reset();
//System.Threading.Thread.Sleep(100);
//manu.Set();
//manu.Reset();
Console.ReadKey();
}
static void Product()
{
lock (objManualResetEvent)
{
manu.WaitOne(10000); manu.Reset();
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
}
}
}
}
执行结果:
到此这篇关于C#中ManualResetEvent 与 AutoResetEvent 区别的文章就介绍到这了,更多相关C#中ManualResetEvent AutoResetEvent 内容请搜索得得之家以前的文章希望大家以后多多支持得得之家!
本文标题为:C#中多线程ManualResetEvent 与 AutoResetEvent 区别


基础教程推荐
- 实例详解C#实现http不同方法的请求 2022-12-26
- C#通过标签软件Bartender的ZPL命令打印条码 2023-05-16
- C#获取指定目录下某种格式文件集并备份到指定文件夹 2023-05-30
- Unity 如何获取鼠标停留位置下的物体 2023-04-10
- C#中 Json 序列化去掉null值的方法 2022-11-18
- C# 解析XML和反序列化的示例 2023-04-14
- Unity shader实现高斯模糊效果 2023-01-16
- C#调用摄像头实现拍照功能的示例代码 2023-03-09
- C#中的Linq to JSON操作详解 2023-06-08
- c# – USING块在网站与Windows窗体中的行为不同 2023-09-20