According to the documentation:
根据文件:
"a
SemaphoreSlim
doesn't use a Windows kernel semaphore".“SemaphoreSlim不使用Windows内核信号量”。
Are there any special resources used by the SemaphoreSlim
which make it important to call Dispose
when the SemaphoreSlim
will no longer be used?
是否有SemaphoreSlim使用的特殊资源,当不再使用SemaphoreSlim时调用Dispose很重要?
4 个解决方案
#1
6
Yes.
It may use a ManualResetEvent
that uses a SafeWaitHandle
which is a SafeHandle
and it has an unmanaged handle.
它可能使用一个使用SafeWaitHandle的ManualResetEvent,它是一个SafeHandle,它有一个非托管句柄。
You can see it in the reference source here.
您可以在参考源中看到它。
SafeHandle
is finalizable so if you don't dispose of it (by disposing of the SemaphoreSlim
) it will go to the finalizer that will need to do that for you. Since the finalizer is a single thread it may get overworked in certain situations so it's always advisable to dispose finalizable objects.
SafeHandle是可以最终确定的,所以如果你不处理它(通过处理SemaphoreSlim),它将转到需要为你完成的终结器。由于终结器是单线程,因此在某些情况下可能会过度工作,因此始终建议配置可终结的对象。
#2
13
If you access the AvailableWaitHandle property, then Yes, you must call Dispose() to cleanup unmanaged resources.
如果您访问AvailableWaitHandle属性,然后是,则必须调用Dispose()来清理非托管资源。
If you do not access AvailableWaitHandle, then No, calling Dispose() won't do anything important.
如果你没有访问AvailableWaitHandle,那么No,调用Dispose()将不会做任何重要的事情。
SemaphoreSlim will create a ManualResetEvent on demand if you access the AvailableWaitHandle. This may be useful, for example if you need to wait on multiple handles. If you do access the AvailableWaitHandle property, and then fail to call Dispose() you will have a leaked ManualResetEvent, which presumably wraps a handle to an unmanaged CreateEvent resource that needs a corresponding call to CloseHandle to clean up.
如果您访问AvailableWaitHandle,SemaphoreSlim将根据需要创建ManualResetEvent。这可能很有用,例如,如果您需要等待多个句柄。如果您确实访问了AvailableWaitHandle属性,然后无法调用Dispose(),那么您将有一个泄漏的ManualResetEvent,它可能会包含一个非托管CreateEvent资源的句柄,该资源需要对CloseHandle进行相应的调用以进行清理。
As other posters have pointed out, you should call Dispose() when you are done with any object that implements IDisposable. In this case, there are several risks to ignoring that practice, even though it may technically be safe to do so:
正如其他海报所指出的,当你完成任何实现IDisposable的对象时,你应该调用Dispose()。在这种情况下,忽略这种做法存在一些风险,即使在技术上可能是安全的:
- My statements are based the reference source code to .NET 4.6.1. There is always the slim (pun intended) possibility that some future version of the framework will change SemaphoreSlim to where Dispose() is required.
- If your SemaphoreSlim is exposed outside of your class, calling code might reference the AvailableWaitHandle property not realizing that your class isn't disposing the SemaphoreSlim and create an unmanaged resource leak.
我的陈述基于.NET 4.6.1的参考源代码。总是有一种纤细(双关语)的可能性,框架的某些未来版本会将SemaphoreSlim更改为需要Dispose()的地方。
如果您的SemaphoreSlim暴露在您的类之外,则调用代码可能会引用AvailableWaitHandle属性,而不会意识到您的类没有处置SemaphoreSlim并创建非托管资源泄漏。
#3
2
You should always call Dispose()
on any class implementing IDisposable
(or put it inside a using
statement) and not base your decision on its internal implementation. The class author already made that decision for you by implementing the IDisposable
interface.
您应该始终在任何实现IDisposable的类上调用Dispose()(或将其置于using语句中),而不是根据其内部实现做出决定。类作者已经通过实现IDisposable接口为您做出了决定。
#4
1
For many other classes I would agree with i3arnon, but for SemaphoreSlim I'll go with Tim's comment. If you use SemaphoreSlim in a low-level class and have to dispose it then practically everything in your program will become IDisposable when in fact it is not necessary. This is all the more true given that AvailableWaitHandle is quite specialized and usually is not used.
对于许多其他课程,我同意i3arnon,但对于SemaphoreSlim,我会选择Tim的评论。如果你在一个低级别的类中使用SemaphoreSlim并且必须处理它,那么几乎你的程序中的所有内容都将成为IDisposable,而实际上它并不是必需的。鉴于AvailableWaitHandle非常专业且通常不使用,因此更为真实。
To protect against other coders accessing the AvailableWaitHandle, you can just wrap it in a non-disposable class. You see this for example in the wrappers by Cleary and by Hanselman, both based on a post by Stephen Toub (which by the way does not Dispose).
为了防止其他编码人员访问AvailableWaitHandle,您可以将其包装在非一次性类中。你可以在Cleary和Hanselman的包装中看到这一点,两者都是基于Stephen Toub的一篇文章(顺便提一下,它没有Dispose)。
P.S. As for the IDisposable contract, it should just be specified in the documentation that Dispose is only needed if AvailableWaitHandle is accessed.
附:至于IDisposable合同,只需在文档中指定只有在访问AvailableWaitHandle时才需要Dispose。
#1
6
Yes.
It may use a ManualResetEvent
that uses a SafeWaitHandle
which is a SafeHandle
and it has an unmanaged handle.
它可能使用一个使用SafeWaitHandle的ManualResetEvent,它是一个SafeHandle,它有一个非托管句柄。
You can see it in the reference source here.
您可以在参考源中看到它。
SafeHandle
is finalizable so if you don't dispose of it (by disposing of the SemaphoreSlim
) it will go to the finalizer that will need to do that for you. Since the finalizer is a single thread it may get overworked in certain situations so it's always advisable to dispose finalizable objects.
SafeHandle是可以最终确定的,所以如果你不处理它(通过处理SemaphoreSlim),它将转到需要为你完成的终结器。由于终结器是单线程,因此在某些情况下可能会过度工作,因此始终建议配置可终结的对象。
#2
13
If you access the AvailableWaitHandle property, then Yes, you must call Dispose() to cleanup unmanaged resources.
如果您访问AvailableWaitHandle属性,然后是,则必须调用Dispose()来清理非托管资源。
If you do not access AvailableWaitHandle, then No, calling Dispose() won't do anything important.
如果你没有访问AvailableWaitHandle,那么No,调用Dispose()将不会做任何重要的事情。
SemaphoreSlim will create a ManualResetEvent on demand if you access the AvailableWaitHandle. This may be useful, for example if you need to wait on multiple handles. If you do access the AvailableWaitHandle property, and then fail to call Dispose() you will have a leaked ManualResetEvent, which presumably wraps a handle to an unmanaged CreateEvent resource that needs a corresponding call to CloseHandle to clean up.
如果您访问AvailableWaitHandle,SemaphoreSlim将根据需要创建ManualResetEvent。这可能很有用,例如,如果您需要等待多个句柄。如果您确实访问了AvailableWaitHandle属性,然后无法调用Dispose(),那么您将有一个泄漏的ManualResetEvent,它可能会包含一个非托管CreateEvent资源的句柄,该资源需要对CloseHandle进行相应的调用以进行清理。
As other posters have pointed out, you should call Dispose() when you are done with any object that implements IDisposable. In this case, there are several risks to ignoring that practice, even though it may technically be safe to do so:
正如其他海报所指出的,当你完成任何实现IDisposable的对象时,你应该调用Dispose()。在这种情况下,忽略这种做法存在一些风险,即使在技术上可能是安全的:
- My statements are based the reference source code to .NET 4.6.1. There is always the slim (pun intended) possibility that some future version of the framework will change SemaphoreSlim to where Dispose() is required.
- If your SemaphoreSlim is exposed outside of your class, calling code might reference the AvailableWaitHandle property not realizing that your class isn't disposing the SemaphoreSlim and create an unmanaged resource leak.
我的陈述基于.NET 4.6.1的参考源代码。总是有一种纤细(双关语)的可能性,框架的某些未来版本会将SemaphoreSlim更改为需要Dispose()的地方。
如果您的SemaphoreSlim暴露在您的类之外,则调用代码可能会引用AvailableWaitHandle属性,而不会意识到您的类没有处置SemaphoreSlim并创建非托管资源泄漏。
#3
2
You should always call Dispose()
on any class implementing IDisposable
(or put it inside a using
statement) and not base your decision on its internal implementation. The class author already made that decision for you by implementing the IDisposable
interface.
您应该始终在任何实现IDisposable的类上调用Dispose()(或将其置于using语句中),而不是根据其内部实现做出决定。类作者已经通过实现IDisposable接口为您做出了决定。
#4
1
For many other classes I would agree with i3arnon, but for SemaphoreSlim I'll go with Tim's comment. If you use SemaphoreSlim in a low-level class and have to dispose it then practically everything in your program will become IDisposable when in fact it is not necessary. This is all the more true given that AvailableWaitHandle is quite specialized and usually is not used.
对于许多其他课程,我同意i3arnon,但对于SemaphoreSlim,我会选择Tim的评论。如果你在一个低级别的类中使用SemaphoreSlim并且必须处理它,那么几乎你的程序中的所有内容都将成为IDisposable,而实际上它并不是必需的。鉴于AvailableWaitHandle非常专业且通常不使用,因此更为真实。
To protect against other coders accessing the AvailableWaitHandle, you can just wrap it in a non-disposable class. You see this for example in the wrappers by Cleary and by Hanselman, both based on a post by Stephen Toub (which by the way does not Dispose).
为了防止其他编码人员访问AvailableWaitHandle,您可以将其包装在非一次性类中。你可以在Cleary和Hanselman的包装中看到这一点,两者都是基于Stephen Toub的一篇文章(顺便提一下,它没有Dispose)。
P.S. As for the IDisposable contract, it should just be specified in the documentation that Dispose is only needed if AvailableWaitHandle is accessed.
附:至于IDisposable合同,只需在文档中指定只有在访问AvailableWaitHandle时才需要Dispose。