C# ManualResetEvent使用方法详解
ManualResetEvent
是C#中的一个线程同步类,它可以在多线程场景下,实现线程等待和唤醒的功能。本文将详细讲解ManualResetEvent
的使用方法。
ManualResetEvent简介
ManualResetEvent
是一个线程同步类,用于在多线程环境下控制线程的等待和唤醒。它主要包含两个方法:
public void WaitOne();
public void Set();
其中WaitOne
方法是线程进入等待状态,直到ManualResetEvent
对象被Set
方法设置为已通知状态。Set
方法则是将ManualResetEvent
对象设置为已通知状态,此时等待它的线程将被唤醒。
ManualResetEvent
的状态有两种:
- 未通知状态(初始状态),线程调用
WaitOne
方法会被阻塞。 - 已通知状态,线程调用
WaitOne
方法不会被阻塞。
使用方法
创建对象
在使用ManualResetEvent
之前,需要先创建对象。可以使用无参构造函数创建一个初始状态为未通知的ManualResetEvent
对象。
ManualResetEvent mre = new ManualResetEvent(false);
也可以使用有参构造函数来创建一个指定状态的ManualResetEvent
对象。
ManualResetEvent mre = new ManualResetEvent(true);
等待和通知
线程可以通过调用WaitOne
方法来等待ManualResetEvent
对象被设置为已通知状态。如果ManualResetEvent
对象已经处于已通知状态,则调用WaitOne
方法时不会被阻塞。
mre.WaitOne();
另外,可以使用WaitOne
方法的重载版本指定等待的超时时间,超过指定时间后如果ManualResetEvent
对象还未被设置为已通知状态,则方法返回false
。
bool result = mre.WaitOne(1000);
线程通过调用Set
方法来设置ManualResetEvent
对象为已通知状态。如果有线程正在等待该对象,则被通知的线程将继续执行。
mre.Set();
需要注意的是,ManualResetEvent
对象只会通知一次。如果有多个线程正在等待它,则只有一个线程会被唤醒。
示例1
下面是一个简单的示例,展示了如何使用ManualResetEvent
实现线程等待和唤醒的功能。
static ManualResetEvent mre = new ManualResetEvent(false);
static void Main(string[] args)
{
Console.WriteLine("Main Thread Start");
Thread t = new Thread(new ThreadStart(WorkerThread));
t.Start();
Console.WriteLine("Main Thread Wait");
// 等待WorkerThread线程执行完毕
mre.WaitOne();
Console.WriteLine("Main Thread End");
}
static void WorkerThread()
{
Console.WriteLine("Worker Thread Start");
Thread.Sleep(3000);
Console.WriteLine("Worker Thread End");
// 通知Main Thread线程已经执行完毕
mre.Set();
}
输出结果:
Main Thread Start
Main Thread Wait
Worker Thread Start
Worker Thread End
Main Thread End
可以看到,Main Thread
线程在调用mre.WaitOne()
方法等待Worker Thread
线程执行完毕,并在mre.Set()
方法被调用后继续执行。
示例2
下面是另一个示例,它展示了如何使用ManualResetEvent
处理一组线程的执行。
class Program
{
static ManualResetEvent[] workerMres = new ManualResetEvent[]
{
new ManualResetEvent(false),
new ManualResetEvent(false),
new ManualResetEvent(false)
};
static void Main(string[] args)
{
Console.WriteLine("Main Thread Start");
for (int i = 0; i < workerMres.Length; i++)
{
int index = i;
Thread t = new Thread(() => WorkerThread(index));
t.Start();
}
Console.WriteLine("Main Thread Wait");
// 等待所有WorkerThread线程执行完毕
WaitHandle.WaitAll(workerMres);
Console.WriteLine("Main Thread End");
}
static void WorkerThread(int index)
{
Console.WriteLine($"Worker Thread {index} Start");
Thread.Sleep((index + 1) * 2000);
Console.WriteLine($"Worker Thread {index} End");
// 通知Main Thread当前线程已经执行完毕
workerMres[index].Set();
}
}
输出结果:
Main Thread Start
Worker Thread 0 Start
Worker Thread 1 Start
Worker Thread 2 Start
Main Thread Wait
Worker Thread 1 End
Worker Thread 2 End
Worker Thread 0 End
Main Thread End
可以看到,Main Thread
线程等待一组Worker Thread
线程执行完毕,并且在所有线程都执行完毕后才继续执行。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C# ManualResetEvent使用方法详解 - Python技术站