Столкнулся с непонятным поведением механизма 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 всё отрабатывает, однако проблема не решена
У вас классическая «гонка» потоков. В вашем случае второй Set
успевает отработать до того, как один из потоков проснётся, и auto
будет сброшен в исходное состояние. У AutoResetEvent
, в отличие от семафора, нету счётчика взведений, а только внутренний флаг «взведён/нет». В результате вы его взводите два раза подряд, он остаётся взведённым, а рабочий поток просыпается позже, сбрасывает его, а снова взвести уже некому.
Вам нужно завести для синхронизации ещё один AutoResetEvent
, который бы сообщал «привет, я проснулся!», устанавливать его в рабочих потоках, и дожидаться между вызовами Set
.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
В случае если текст длиннее чем Label, как сделать так, чтобы этот текст плыл в левую сторону, потом появлялся снова и после небольшой паузы снова...
Я вывожу в TextBlock адрес электронной почтыКак сделать, чтобы при нажатии на него открывалось окно создания нового письма?