AutoResetEvent
是 C# 中一個非常有用的同步原語,它允許一個或多個線程等待,直到另一個線程發出信號為止。AutoResetEvent
在某些場景下非常有用,比如生產者-消費者模式、線程池等。以下是一些使用 AutoResetEvent
的案例:
生產者-消費者模式是一種常見的并發編程模式,其中一個或多個生產者線程生成數據并將其放入共享緩沖區(隊列),而一個或多個消費者線程從共享緩沖區中取出數據并進行處理。AutoResetEvent
可以用于同步生產者和消費者線程。
using System;
using System.Threading;
class ProducerConsumer
{
private static AutoResetEvent _producerReady = new AutoResetEvent(false);
private static AutoResetEvent _consumerReady = new AutoResetEvent(true);
private static int[] _buffer = new int[10];
private static int _producerIndex = 0;
private static int _consumerIndex = 0;
static void Main()
{
Thread producerThread = new Thread(Producer);
Thread consumerThread = new Thread(Consumer);
producerThread.Start();
consumerThread.Start();
producerThread.Join();
consumerThread.Join();
}
static void Producer()
{
while (true)
{
_producerReady.WaitOne(); // 等待消費者準備好
_buffer[_producerIndex] = GenerateProduct();
_producerIndex = (_producerIndex + 1) % _buffer.Length;
Console.WriteLine("Produced: " + _buffer[_producerIndex]);
_consumerReady.Set(); // 通知消費者
}
}
static void Consumer()
{
while (true)
{
_consumerReady.WaitOne(); // 等待生產者準備好
int product = _buffer[_consumerIndex];
_consumerIndex = (_consumerIndex + 1) % _buffer.Length;
Console.WriteLine("Consumed: " + product);
_producerReady.Set(); // 通知生產者
}
}
static int GenerateProduct()
{
return new Random().Next();
}
}
AutoResetEvent
也可以用于線程池中的任務調度。線程池允許你重用已經創建的線程,從而減少線程創建和銷毀的開銷。你可以使用 AutoResetEvent
來同步線程池中的任務,確保它們按照預期的順序執行。
注意:在實際應用中,線程池的使用通常會更加復雜,涉及到任務的排隊、執行、完成等。上面的示例僅用于演示 AutoResetEvent
的基本用法。
AutoResetEvent
還可以用于同步多個線程,確保它們按照預期的順序執行。例如,你可以使用 AutoResetEvent
來確保主線程在繼續執行之前等待其他線程完成某些操作。
using System;
using System.Threading;
class SynchronizeThreads
{
private static AutoResetEvent _event = new AutoResetEvent(false);
static void Main()
{
Thread thread1 = new Thread(Thread1);
Thread thread2 = new Thread(Thread2);
thread1.Start();
thread2.Start();
_event.WaitOne(); // 等待線程1完成
_event.Set(); // 通知主線程繼續執行
thread1.Join();
thread2.Join();
}
static void Thread1()
{
Console.WriteLine("Thread 1 started.");
Thread.Sleep(1000); // 模擬耗時操作
Console.WriteLine("Thread 1 completed.");
_event.Set(); // 通知主線程繼續執行
}
static void Thread2()
{
_event.WaitOne(); // 等待線程1完成
Console.WriteLine("Thread 2 started.");
Thread.Sleep(1000); // 模擬耗時操作
Console.WriteLine("Thread 2 completed.");
}
}
這些示例展示了 AutoResetEvent
在不同場景下的基本用法。你可以根據自己的需求調整代碼以滿足特定的同步需求。