.net 我是否需要释放一个SemaphoreSlim?

pgky5nke  于 2023-03-04  发布在  .NET
关注(0)|答案(4)|浏览(139)

根据文件:
"SemaphoreSlim不使用Windows内核信号量"。
SemaphoreSlim是否使用了任何特殊资源,使得在不再使用SemaphoreSlim时调用Dispose变得非常重要?

tct7dpnv

tct7dpnv1#

如果访问AvailableWaitHandle属性,则选择Yes,则必须调用Dispose()来清除非托管资源。
如果您不访问AvailableWaitHandle则否,调用Dispose()不会执行任何重要操作。
如果您访问AvailableWaitHandleSemaphoreSlim将按需创建ManualResetEvent。这可能很有用,例如,如果您需要等待多个句柄。如果您确实访问了AvailableWaitHandle属性,然后未能调用Dispose(),则ManualResetEvent将泄漏。这可能 Package 了一个指向非托管CreateEvent资源的句柄,该资源需要对CloseHandle的相应调用来清除。
正如其他人所指出的,当您处理完任何实现IDisposable的对象时,您应该调用Dispose()。在这种情况下,忽略这种做法有几个风险,即使这样做在技术上可能是安全的:
1.我的声明基于.NET 4.6.1的参考源代码。框架的某些未来版本将SemaphoreSlim更改为需要Dispose()的地方,这种可能性很小(双关语)。
1.如果SemaphoreSlim在类外部公开,则调用代码可能会引用AvailableWaitHandle属性,而没有意识到类没有释放SemaphoreSlim,从而导致非托管资源泄漏。

zbdgwd5y

zbdgwd5y2#

是的。
它可能使用ManualResetEvent,而SafeWaitHandle使用的是SafeHandle,并且具有非托管句柄。
您可以在此处的参考源中看到它。
SafeHandle是可终结的,所以如果你不释放它(通过释放SemaphoreSlim),它将转到终结器,终结器将需要为你做这件事。由于终结器是一个单线程,它可能会在某些情况下过度工作,所以建议总是释放可终结的对象。

crcmnpdw

crcmnpdw3#

对于许多其他的类,我同意i3arnon,但是对于SemaphoreSlim,我同意Tim的意见。如果你在一个低级类中使用SemaphoreSlim,并且不得不释放它,那么实际上你程序中的所有东西都将变成IDisposable,而实际上这是不必要的。考虑到AvailableWaitHandle是非常专门化的,通常不使用它,这就更正确了。
为了防止其他程序员访问AvailableWaitHandle,你可以将它 Package 在一个不可释放的类中,例如,你可以在Cleary和Hanselman的 Package 器中看到这一点,这两个 Package 器都基于Stephen Toub的帖子(顺便说一句,没有Dispose)。
P.S.至于IDisposable契约,应该在文档中指定只有在访问AvailableWaitHandle时才需要Dispose。

wwodge7n

wwodge7n4#

你应该总是在任何实现IDisposable的类上调用Dispose()(或者把它放在using语句中),而不是根据它的内部实现来做决定。类的作者已经通过实现IDisposable接口为你做了这个决定。

相关问题