我是否需要配置SemaphoreSlim
根据文件:
“
SemaphoreSlim
不使用Windows内核信号量”。
是否有SemaphoreSlim
使用的特殊资源,当不再使用SemaphoreSlim
时调用Dispose
很重要?
是。
它可能使用一个使用SafeWaitHandle
的ManualResetEvent
,它是一个SafeHandle
,它有一个非托管句柄。
您可以在参考源中看到它。
SafeHandle
是可以最终确定的,所以如果你不处理它(通过处理SemaphoreSlim
),它将转到需要为你完成的终结器。 由于终结器是单线程,因此在某些情况下可能会过度工作,因此始终建议配置可终结的对象。
如果您访问AvailableWaitHandle属性, 然后是 ,则必须调用Dispose()来清理非托管资源。
如果你没有访问AvailableWaitHandle, 那么No ,调用Dispose()将不会做任何重要的事情。
如果您访问AvailableWaitHandle,SemaphoreSlim将根据需要创建ManualResetEvent。 这可能很有用,例如,如果您需要等待多个句柄。 如果您确实访问了AvailableWaitHandle属性,然后无法调用Dispose(),那么您将有一个泄漏的ManualResetEvent,它可能会包含一个非托管CreateEvent资源的句柄,该资源需要对CloseHandle进行相应的调用以进行清理。
正如其他海报所指出的,当你完成任何实现IDisposable的对象时,你应该调用Dispose()。 在这种情况下,忽略这种做法存在一些风险,即使在技术上可能是安全的:
- 我的陈述基于.NET 4.6.1的参考源代码。 总是有一种纤细(双关语)的可能性,框架的某些未来版本会将SemaphoreSlim更改为需要Dispose()的地方。
- 如果您的SemaphoreSlim暴露在您的类之外,则调用代码可能会引用AvailableWaitHandle属性,而不会意识到您的类没有处置SemaphoreSlim并创建非托管资源泄漏。
您应该始终在任何实现IDisposable
类上调用Dispose()
(或将其置于using
语句中),而不是根据其内部实现做出决定。 类作者已经通过实现IDisposable
接口为您做出了决定。
对于许多其他课程,我同意i3arnon,但对于SemaphoreSlim,我会选择Tim的评论。 如果你在一个低级别的类中使用SemaphoreSlim并且必须处理它,那么几乎你的程序中的所有内容都将成为IDisposable,而实际上它并不是必需的。 鉴于AvailableWaitHandle非常专业且通常不使用,因此更为真实。
为了防止其他编码人员访问AvailableWaitHandle,您可以将其包装在非一次性类中。 你可以在Cleary和Hanselman的包装中看到这一点,两者都是基于Stephen Toub的一篇文章(顺便提一下,它没有Dispose)。
PS对于IDisposable合同,只应在文档中指定只有在访问AvailableWaitHandle时才需要Dispose。