События в порядке, просто не используйте PulseEvent.Microsoft не только безнадежно испортила реализацию, но и усложнила ее использование в условиях гонки.Если событие происходит непосредственно перед тем, как поток блокирует событие, событие будет потеряно.Вместо этого используйте события ручного сброса.
Для блокировки:
B1) Установите для блокировки событие.
B2) Проверьте, чтобы событие еще не произошлои убедитесь, что хотите заблокировать это.Если необходимо, поместите событие в общую структуру данных, чтобы разбудившие нас потоки заметили его.
B3) Блокировать событие.
Пробудить:
W1) Обновитьобщие данные, чтобы отразить тот факт, что событие произошло.
W2) Разблокировать событие.При необходимости просмотрите общую структуру данных и разблокируйте все события, связанные с тем, что только что произошло.
Здесь нет условия гонки.Если событие происходит после B1 или B2, но до B3, блок в B3 фактически не будет блокироваться, потому что W2 разблокирует его.Если событие уже произошло до W1, поток никогда не заблокируется, потому что B2 увидит влияние W1, и мы никогда не доберемся до B3.
В большинстве случаев операции B2 и W2 необходимо выполнять, покаудержание блокировки, используемой всеми потоками, которые обрабатывают события этого типа.