浅谈C#之AutoResetEvent和ManualResetEvent
一、基本介绍
AutoResetEvent
和ManualResetEvent
都是同步原语,它们用于线程之间的协调和通信。它们都是从EventWaitHandle
类派生的,但它们在重置事件状态的行为上有所不同。
二、简单示例
AutoResetEvent
AutoResetEvent
是一个自动重置的事件。当一个线程调用Set
方法后,任何等待该事件的线程都会被释放,然后事件会自动回到非信号状态(即,它会自动重置)。这意味着如果只有一个线程在等待,那么这个线程会被释放,如果有更多的线程在等待,那么只有一个线程会被释放,其余的线程会继续等待。
using System.Threading;
class Program
{
static AutoResetEvent autoEvent = new AutoResetEvent(false);
static void Main()
{
Thread t = new Thread(DoWork);
t.Start();
autoEvent.WaitOne(); // 等待事件被设置
Console.WriteLine("Main thread is now free to exit.");
}
static void DoWork()
{
Console.WriteLine("Worker thread is working.");
autoEvent.Set(); // 设置事件,释放等待的线程
}
}
ManualResetEvent
ManualResetEvent
是一个手动重置的事件。与AutoResetEvent
不同,当一个线程调用Set
方法后,所有等待该事件的线程都会被释放,但是事件不会自动重置,它将保持在信号状态,直到调用Reset
方法。这意味着如果有更多的线程在等待,那么所有等待的线程都会被释放。
using System.Threading;
class Program
{
static ManualResetEvent manualEvent = new ManualResetEvent(false);
static void Main()
{
Thread t = new Thread(DoWork);
t.Start();
manualEvent.WaitOne(); // 等待事件被设置
Console.WriteLine("Main thread is now free to exit.");
}
static void DoWork()
{
Console.WriteLine("Worker thread is working.");
manualEvent.Set(); // 设置事件,释放等待的线程
}
}
三、使用场景
- AutoResetEvent:当你希望每次只有一个等待线程被释放时使用。
- ManualResetEvent:当你希望所有等待线程都被释放时使用,或者你需要在多个地方重置事件状态时使用。