Почему в BCL нет класса AutoResetEventSlim
?
Можно ли имитировать с помощью ManualResetEventSlim
?
Почему в BCL нет класса AutoResetEventSlim
?
Можно ли имитировать с помощью ManualResetEventSlim
?
ManualResetEvent
и ManualResetEventSlim
оба предназначены так, чтобы они оставались сигналами после вызова. Обычно это имеет совсем другой сценарий, чем AutoResetEvent
.
AutoResetEvent
немедленно возвращается в состояние unsignaled после использования, которое обычно используется для другого набора сценариев. Из документации AutoResetEvents:
Как правило, вы используете этот класс, когда потоки нуждаются в эксклюзивном доступе к ресурсу.
ManualResetEvent
(и Slim
) обычно используются, однако, для сценария, в котором:
это сообщение относится к задаче, которую должен выполнить один поток, прежде чем другие потоки могут продолжить.
Так как AutoResetEvent
чаще всего используется в сценариях, где есть несколько потоков, совместно использующих ресурс, времена ожидания обычно не будут чрезвычайно короткими. ManualResetEventSlim
, однако, действительно предназначен только тогда, когда вы заранее знаете, что время ожидания очень короткое. Если ваше время ожидания не будет очень коротким, тогда вы должны использовать ManualResetEvent
. Подробнее см. Документацию по разнице между MRE и MRES.
Когда время ожидания больше (это будет обычный сценарий с AutoResetEvent
), "тонкая" версия на самом деле хуже, поскольку она возвращается к использованию дескриптора ожидания.
Я был прослушан этим фактом также.
Однако, похоже, что вы можете смоделировать 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()
, который можно ожидать. Таким образом, в этом случае больше не нужно вручную создавать ожидающий примитив ожидания.
Надеюсь это поможет.