我需要 Dispose() 或 Close() EventWaitHandle 吗?

Posted

技术标签:

【中文标题】我需要 Dispose() 或 Close() EventWaitHandle 吗?【英文标题】:Do I need to Dispose() or Close() an EventWaitHandle? 【发布时间】:2010-10-14 04:13:12 【问题描述】:

如果我使用EventWaitHandle(或AutoResetEventManualResetEvent)在线程之间进行同步,那么当我完成后是否需要在该事件句柄上调用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(或AutoResetEventManualResetEvent

【讨论】:

以上是关于我需要 Dispose() 或 Close() EventWaitHandle 吗?的主要内容,如果未能解决你的问题,请参考以下文章

更改“ReproClass”上的 Dispose 方法以在此字段上调用 ​​Dispose 或 Close

处理 WebSocket 的类 close 和 dispose (Observable.Using)

SQL中的close和dispose有啥区别? [复制]

Close and Dispose - 调用哪个?

深入解析Close()和Dispose()的区别

Stream.Dispose 是不是总是调用 Stream.Close(和 Stream.Flush)