我需要 Dispose() 或 Close() EventWaitHandle 吗?
Posted
技术标签:
【中文标题】我需要 Dispose() 或 Close() EventWaitHandle 吗?【英文标题】:Do I need to Dispose() or Close() an EventWaitHandle? 【发布时间】:2010-10-14 04:13:12 【问题描述】:如果我使用EventWaitHandle
(或AutoResetEvent
、ManualResetEvent
)在线程之间进行同步,那么当我完成后是否需要在该事件句柄上调用Close()
或Dispose()
方法?
EventWaitHandle
继承自 WaitHandle
,后者实现了 IDisposable
。如果我没有在任何包含EventWaitHandle
的类上实现IDisposable
,FxCop 就会抱怨。所以这表明我确实需要调用它。
但是,这些 MSDN 使用示例都没有调用 Dispose()
或 Close()
:
http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle(VS.80).aspx http://msdn.microsoft.com/en-us/library/system.threading.manualresetevent(VS.80).aspx http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent(VS.80).aspx
这只是微软无视自己建议的一个例子吗?
【问题讨论】:
【参考方案1】:EventWaitHandle
的一次性资源实际上是SafeHandle
(包装在SafeWaitHandle
中)。 SafeHandle
实现了一个终结器,它最终确保释放必要的资源,因此让垃圾收集器/终结器线程处理它应该是安全的在这种情况下。
但是,当不再需要资源时,显式调用Dispose()
总是一个好主意。
C# 3.0 in a Nutshell 状态下的线程章节
这种做法(可以说)是可以接受的 带有等待句柄,因为它们有一个 轻操作系统负担(异步 代表完全依赖这种机制 释放他们
IAsyncResult
的等待 句柄)。
【讨论】:
我认为让 GC 收集它是非常不可取的。将工作留给 Finalizer 线程只是不好的做法。只有一个终结器线程并导致它做的比它真正应该做的更多是不好的。如果线程被阻塞,您的应用程序将挂起。如果在终结器线程上引发异常,您的 AppDomain 将崩溃。拥有正确的处置模式可以保证调用 GC.SuppressFinalize() 从而抑制该对象的终结。我有一个实现 IDisposable 的示例 - dave-black.blogspot.com/2011/03/… 我同意,这就是为什么我声明您应该明确致电Dispose
。【参考方案2】:
您需要明确处置它们。 Close() 更适合他们,因为它确实调用了 Dispose()。
【讨论】:
【参考方案3】:来自 MSDN 的类定义:
public class EventWaitHandle : WaitHandle
public abstract class WaitHandle : MarshalByRefObject, IDisposable
所以是的,你必须因为 WaitHandle 是 IDisposable。如果您不这样做,FxCop 会认为这是违规行为。
【讨论】:
感谢 Peter,但为什么 MSDN 使用示例不调用 Close() 或 Dispose()?这只是微软没有遵循他们自己的建议吗? 我猜有 50% 的人没有遵循他们自己的建议,还有 50% 的人试图让示例尽可能简短……还有编写示例的人的配菜(不是核心 sdk开发人员)不知道更好。 @PeterDrier 示例使用静态等待句柄。【参考方案4】:Close 方法在内部处理它。
【讨论】:
【参考方案5】:MSDN says:
在释放对 WaitHandle 的最后一个引用之前,始终调用 Close 或 Dispose()。否则,它正在使用的资源将不会被释放。
因此,由于它们继承了WaitHandle
,在我看来,您也应该处置EventWaitHandle
(或AutoResetEvent
、ManualResetEvent
)
【讨论】:
以上是关于我需要 Dispose() 或 Close() EventWaitHandle 吗?的主要内容,如果未能解决你的问题,请参考以下文章
更改“ReproClass”上的 Dispose 方法以在此字段上调用 Dispose 或 Close