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