Неявный принцип работы AutoResetEvent

241
19 мая 2017, 12:47

Столкнулся с непонятным поведением механизма AutoResetEvent.

Есть следующих код:

static void Main()
{
    new Thread(Method1).Start();
    new Thread(Method2).Start();
    Thread.Sleep(500);
    Console.WriteLine("нажмите любую клавишу");
    Console.ReadKey();
    auto.Set();            
    auto.Set(); 
    Console.ReadKey();
}

к нему есть пара методов:

static void Method1()
{
    Console.WriteLine("Метод 1 запущен");
    auto.WaitOne();
    Console.WriteLine("Метод 1 остановлен");
}
static void Method2()
{
    Console.WriteLine("Метод 2 запущен");
    auto.WaitOne();
    Console.WriteLine("Метод 2 остановлен");
}

Судя по описанию AutoResetEvent, метод Set() должен отправлять сигнал только одному потоку, т.е. каждый вызов метода Set() будит один из двух запущенных методов. Соответственно отработать должны оба. Но в данном случае до конца отрабатывает только один из методов, программа при этом зависает. С чем может быть связано такое поведение?

-------------^^UPD При запуске через f11 всё отрабатывает, однако проблема не решена

Answer 1

У вас классическая «гонка» потоков. В вашем случае второй Set успевает отработать до того, как один из потоков проснётся, и auto будет сброшен в исходное состояние. У AutoResetEvent, в отличие от семафора, нету счётчика взведений, а только внутренний флаг «взведён/нет». В результате вы его взводите два раза подряд, он остаётся взведённым, а рабочий поток просыпается позже, сбрасывает его, а снова взвести уже некому.

Вам нужно завести для синхронизации ещё один AutoResetEvent, который бы сообщал «привет, я проснулся!», устанавливать его в рабочих потоках, и дожидаться между вызовами Set.

READ ALSO
Плавающий текст в Label

Плавающий текст в Label

В случае если текст длиннее чем Label, как сделать так, чтобы этот текст плыл в левую сторону, потом появлялся снова и после небольшой паузы снова...

245
c# ошибка в приложении

c# ошибка в приложении

При нажатии кнопки выходит ошибка:

206
Изменений содержимого окна по кнопкам

Изменений содержимого окна по кнопкам

ЗдравствуйтеНеобходимо разделить форму на 3 части

231
Как сделать ссылку на email рабочей (windows phone 8.1)?

Как сделать ссылку на email рабочей (windows phone 8.1)?

Я вывожу в TextBlock адрес электронной почтыКак сделать, чтобы при нажатии на него открывалось окно создания нового письма?

227