Что такое AutoResetEvent?

«Что такое AutoResetEvent?» — вопрос из категории Многопоточность, который задают на 28% собеседований C# Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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).