Согласно документации:
"a
SemaphoreSlim
не использует семафор ядра Windows".
Существуют ли какие-либо специальные ресурсы, используемые SemaphoreSlim
, которые делают важным вызов Dispose
, когда SemaphoreSlim
больше не будет использоваться?
Согласно документации:
"a
SemaphoreSlim
не использует семафор ядра Windows".
Существуют ли какие-либо специальные ресурсы, используемые SemaphoreSlim
, которые делают важным вызов Dispose
, когда SemaphoreSlim
больше не будет использоваться?
Да.
Он может использовать ManualResetEvent
, который использует SafeWaitHandle
, который является SafeHandle
, и имеет неуправляемый дескриптор.
Вы можете увидеть его здесь в ссылке здесь.
SafeHandle
является окончательным, поэтому, если вы не распоряжаетесь им (путем утилизации SemaphoreSlim
), он перейдет к финализатору, который должен будет сделать это за вас. Поскольку финализатор представляет собой один поток, он может перегружаться в определенных ситуациях, поэтому всегда рекомендуется располагать объекты, подлежащие окончательной обработке.
Если вы используете свойство AvailableWaitHandle, , затем Да, вы должны вызвать Dispose() для очистки неуправляемых ресурсов.
Если вы не получили доступ к доступнойWaitHandle, , то No, вызов Dispose() не будет делать ничего важного.
SemaphoreSlim будет создавать ManualResetEvent по требованию, если вы получите доступ к доступномуWaitHandle. Это может быть полезно, например, если вам нужно ждать нескольких дескрипторов. Если вы выполняете доступ к свойству AvailableWaitHandle, а затем не можете вызвать Dispose(), у вас будет утечка ManualResetEvent, который предположительно переносит дескриптор на неуправляемый ресурс CreateEvent, для которого требуется соответствующий вызов CloseHandle для очистки.
Как отмечали другие плакаты, вы должны вызывать Dispose(), когда закончите с любым объектом, который реализует IDisposable. В этом случае существует несколько рисков для игнорирования этой практики, хотя это может быть технически безопасно:
Вы всегда должны вызывать Dispose()
для любого класса, реализующего IDisposable
(или помещать его в оператор using
), а не основывать свое решение на его внутренней реализации. Автор класса уже принял это решение для вас, реализовав интерфейс IDisposable
.
Для многих других классов я бы согласился с i3arnon, но для SemaphoreSlim я поеду с комментарием Тима. Если вы используете SemaphoreSlim в классе низкого уровня и должны его утилизировать, то практически все в вашей программе станет IDisposable, если на самом деле это не обязательно. Это тем более верно, что AvailableWaitHandle довольно специализирован и обычно не используется.
Для защиты от других кодеров, обращающихся к доступномуWaitHandle, вы можете просто обернуть его в класс, который нельзя использовать. Вы видите это, например, в обертках Клири и Гензельма, оба основаны на записи Стивена Тууба (который, кстати, не Dispose).
P.S. Что касается договора IDisposable, его следует указывать только в документации, которую Dispose требуется только в том случае, если доступ к ДоступнойWaitHandle.