Почему в BCL нет AutoResetEventSlim?

Почему в BCL нет класса AutoResetEventSlim?

Можно ли это смоделировать с помощью ManualResetEventSlim?


person user629926    schedule 21.11.2011    source источник
comment
AutoResetEventSlim можно смоделировать с помощью SemaphoreSlim.   -  person svick    schedule 30.01.2013


Ответы (2)


ManualResetEvent и ManualResetEventSlim спроектированы таким образом, чтобы они оставались в состоянии сигнализации после вызова. Обычно это совсем другой сценарий, чем AutoResetEvent.

AutoResetEvent немедленно возвращается в несигнальное состояние после использования, которое обычно используется для другого набора сценариев. Из документации AutoResetEvents:

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

Однако ManualResetEventSlim) обычно используются в сценариях, где:

это сообщение относится к задаче, которую должен завершить один поток, прежде чем другие потоки смогут продолжить работу.

Поскольку AutoResetEvent чаще всего используется в сценариях с несколькими потоками, совместно использующими ресурс, время ожидания обычно не будет очень коротким. ManualResetEventSlim, однако, на самом деле предназначен только тогда, когда вы заранее знаете, что время ожидания очень короткое. Если ваше время ожидания не будет очень коротким, вместо этого вам следует использовать ManualResetEvent. Дополнительные сведения см. в документации по различиям между MRE и MRES.

Когда ваше время ожидания больше (что было бы нормальным сценарием с AutoResetEvent), «тонкая» версия на самом деле хуже, поскольку она возвращается к использованию дескриптора ожидания.

person Reed Copsey    schedule 21.11.2011

Меня тоже смутил этот факт. Однако похоже, что вы можете имитировать AutoResetEvent(Slim), используя простой SemaphoreSlim с специальная конфигурация:

SemaphoreSlim Lock = new SemaphoreSlim( 1, 1 );

В конструкторе первый параметр определяет начальный состояние семафора: 1 означает, что может войти один поток, 0 что семафор должен быть освобожден первым. Таким образом, new AutoResetEvent( true ) переводится в new SemaphoreSlim( 1, 1 ), а new AutoResetEvent( false ) переводится в new SemaphoreSlim( 0, 1 ) соответственно.

Второй параметр определяет максимальное количество потоков, которые могут одновременно войти в семафор. Установка его на 1 позволяет вести себя как AutoResetEvent.

Еще одна приятная особенность SemaphoreSlim заключается в том, что с новым шаблоном async/await в 4.5 класс получил .WaitAsync() метод, который можно ожидать. Таким образом, в этом случае больше нет необходимости вручную создавать ожидаемый примитив ожидания.

Надеюсь это поможет.

person Simon Mattes    schedule 13.09.2014