我是否需要处理SemaphoreSlim

时间:2015-08-16 08:59:47

标签: c# .net semaphore dispose idisposable

根据文件:

  

" SemaphoreSlim没有使用Windows内核信号量"。

SemaphoreSlim是否使用了哪些特殊资源,在Dispose将不再使用时调用SemaphoreSlim非常重要?

2 个答案:

答案 0 :(得分:15)

如果您访问AvailableWaitHandle属性然后是,则必须调用Dispose()来清理非托管资源。

如果您没有访问AvailableWaitHandle,然后没有,则调用Dispose()不会做任何重要事情。

如果您访问AvailableWaitHandle,SemaphoreSlim将根据需要创建ManualResetEvent。这可能很有用,例如,如果您需要等待多个句柄。如果您确实访问了AvailableWaitHandle属性,然后无法调用Dispose(),那么您将有一个泄漏的ManualResetEvent,它可能会包含一个非托管CreateEvent资源的句柄,该资源需要对CloseHandle进行相应的调用以进行清理。

正如其他海报所指出的,当你完成任何实现IDisposable的对象时,你应该调用Dispose()。在这种情况下,忽略这种做法存在一些风险,即使在技术上可能是安全的:

  1. 我的陈述基于.NET 4.6.1的参考源代码。总是有一种渺茫(双关语)的可能性,框架的某些未来版本会将SemaphoreSlim更改为需要Dispose()的地方。
  2. 如果您的SemaphoreSlim暴露在您的类之外,则调用代码可能会引用AvailableWaitHandle属性,而不会意识到您的类没有处置SemaphoreSlim并创建非托管资源泄漏。

答案 1 :(得分:1)

对于许多其他课程,我同意i3arnon,但对于SemaphoreSlim,我会和Tim发表评论。如果你在一个低级别的类中使用SemaphoreSlim并且必须处理它,那么几乎你的程序中的所有内容都将成为IDisposable,而实际上它并不是必需的。鉴于AvailableWaitHandle非常专业且通常不使用,因此更为真实。

为了防止其他编码人员访问AvailableWaitHandle,您可以将其包装在非一次性类中。你可以在Cleary和Hanselman的包装中看到这一点,两者都是基于Stephen Toub的一篇文章(顺便提一下,它没有Dispose)。

P.S。至于IDisposable合同,只需在文档中指定只有在访问AvailableWaitHandle时才需要Dispose。