Ответ
AutoResetEvent — это примитив синхронизации потоков из пространства имен System.Threading. Он действует как "турникет" или сигнальный механизм "один к одному": один вызов Set() разблокирует ровно один ожидающий поток, после чего событие автоматически сбрасывается в несигнальное состояние.
Основные методы:
WaitOne(): Блокирует текущий поток до тех пор, пока событие не получит сигнал (вызовSet()).Set(): Переводит событие в сигнальное состояние, разрешая продолжить выполнение одному ожидающему потоку. Если ожидающих потоков нет, состояние остается сигнальным до первого вызоваWaitOne().
Практический пример (производитель-потребитель):
// Событие, сигнализирующее о наличии данных
private AutoResetEvent _dataReady = new AutoResetEvent(false);
private Queue<string> _buffer = new Queue<string>();
void Producer()
{
while (true)
{
var data = GenerateData();
lock (_buffer) { _buffer.Enqueue(data); }
// Сигнализируем потребителю, что данные готовы
_dataReady.Set();
Thread.Sleep(1000);
}
}
void Consumer()
{
while (true)
{
// Ожидаем сигнала от производителя
_dataReady.WaitOne();
string data;
lock (_buffer) { data = _buffer.Dequeue(); }
ProcessData(data);
}
}
Ключевое отличие от ManualResetEvent:
AutoResetEvent:Set()разблокирует один поток и автоматически сбрасывается. Как турникет, который пропускает одного человека и закрывается.ManualResetEvent:Set()переводит событие в сигнальное состояние и оставляет его открытым, разблокируя все ожидающие потоки. Чтобы закрыть, требуется явный вызовReset(). Работает как ворота.
Современная альтернатива: Для новых проектов часто предпочтительнее использовать SemaphoreSlim или TaskCompletionSource<T>, которые лучше интегрируются с асинхронным кодом (async/await).