ManualResetEvent 用于表示线程同步事件,可以使得线程等待信号发射之后才继续执行下一步,否则一直处于等待状态中。
ManualResetEvent 的常用方法
构造函数ManualResetEvent(bool);
ManualResetEvent manualResetEvent = new ManualResetEvent(false);
//false 将初始状态设置为无信号
//true 将初始状态设置为有信号
Reset()
复位操作,将状态设置为无信号,如果线程在等待信号的话,那么该线程被阻塞等待。
Set()
设置, 将状态设置为有信号,在等待的线程(可能是一个或多个线程)可以继续执行。
manuaRest.WaitOne()
manuaRest.WaitOne(Int32)
有多个重载方法,阻止当前线程,直到收到信号为止。
例子
下面的demo演示了ManualResetEvent 在线程中的简单使用,功能很简单,就是点击开始按钮之后,启动线程,等待线程执行完之后再将结果输出来。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;namespace MutilThRead
{public partial class Form1 : Form{ManualResetEvent manuaRest;Thread tempThread;int Sum;public Form1(){InitializeComponent();Sum = 0;manuaRest = new ManualResetEvent(false);this.Load += new EventHandler(Form1_Load);}private void Form1_Load(object sender, EventArgs e){this.button1.Click += new EventHandler(button1_Click);}/// <summary>/// 开始按钮/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button1_Click(object sender, EventArgs e){if(tempThread != null){tempThread = null;}Sum = 0;tempThread = new Thread(ThreadRun);tempThread.Start(); //开始线程manuaRest.Reset(); //进入没有信号状态manuaRest.WaitOne(); //阻塞等待//等待线程执行完 manuaRest.Set()释放信号之后,才会执行后面的代码richTextBox1.Text = Sum.ToString();MessageBox.Show("Sum is " + Sum.ToString());}/// <summary>/// 线程运行/// </summary>private void ThreadRun(){for (int i = 1; i < 10000; i = i*2){Sum += i;Thread.Sleep(100);Console.WriteLine(" Thread execute at {0} ", i.ToString());}manuaRest.Set(); //释放信号,指示等待的线程可以继续往下走}}
}
ManualResetEvent 是一个非常好用的线程信号源 用于线程上下文同步,还有一个类似的是AutoResetEvent
可以在MSDN中查看详情https://learn.microsoft.com/zh-cn/dotnet/api/system.threading.autoresetevent?view=net-8.0