Правильно уведомляя всех слушателей именованного ручного события сброса в масштабе всей системы и затем сразу сбрасывая его

Ответ Патрика Артнера содержит то, что я искал, просматривая перечисление с оператором if, сохраняя нужные элементы.

Только что извлекли соответствующие биты.

MySubset = Enum("MySubet", [(a.name, a.value) for a in MyEnum if a.value > 2 ] )

Кажется, эквивалентно (без уникального декоратора):

class MySubset(Enum):
    THREE = 3
    FOUR = 4
6
задан Jeff Moser 9 January 2009 в 21:12
поделиться

2 ответа

Вы используете класс EventWaitHandle неправильно. Событие сброса не должно использоваться для передачи сигналов о нескольких потоках. Вместо этого необходимо создать событие сброса для каждого потока и затем когда Вы - готовый цикл через них всех и используете Набор (). Основной поток не должен называть Сброс () методом. Каждый поток должен быть ответственен за закрытие логического элемента позади них так сказать.

Вот основной пример:

static class Program
{
    static void Main()
    {
        List<ThreadState> states = new List<ThreadState>();
        ThreadState myState;
        Thread myThread;
        string data = "";

        for (int i = 0; i < 4; i++)
        {
            myThread = new Thread(Work);
            myState = new ThreadState();
            myState.gate = new EventWaitHandle(false, EventResetMode.ManualReset);
            myState.running = true;
            myState.index = i + 1;
            states.Add(myState);
            myThread.Start(myState);
        }

        Console.WriteLine("Enter q to quit.");

        while (data != "q")
        {
            data = Console.ReadLine();
            if (data != "q")
                foreach (ThreadState state in states)
                    state.gate.Set();
        }

        foreach (ThreadState state in states)
        {
            state.running = false;
            state.gate.Set();
        }

        Console.WriteLine("Press any key to quit.");
        Console.ReadKey();
    }

    static void Work(Object param)
    {
        ThreadState state = (ThreadState)param;
        while (state.running)
        {
            Console.WriteLine("Thread #" + state.index + " waiting...");
            state.gate.WaitOne();
            Console.WriteLine("Thread #" + state.index + " gate opened.");
            state.gate.Reset();
            Console.WriteLine("Thread #" + state.index + " gate closed.");
        }
        Console.WriteLine("Thread #" + state.index + " terminating.");
    }

    private class ThreadState
    {
        public int index;
        public EventWaitHandle gate;
        public bool running;
    }
}
2
ответ дан 17 December 2019 в 04:53
поделиться

Вы используете неправильный тип синхронизации здесь. Вместо события необходимо использовать Семафорный класс с количеством одновременных доступов, которые Вы хотите разрешить.

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

0
ответ дан 17 December 2019 в 04:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: