我需要对 ManualResetEvent 调用 Close() 吗?
我一直在阅读 .NET Threading 并正在研究一些使用 手动重置事件。我在互联网上找到了很多代码示例。但是,在阅读 WaitHandle 的文档时,我看到下列:
WaitHandle 实现 Dispose 图案。请参阅实施 Finalize 和 处置清理非托管 资源。
似乎没有一个示例在它们创建的 ManualResetEvent 对象上调用 .Close(),即使是很好的 递归和并发来自 pfxteam 博客的文章(编辑 - 这有一个 using 块我错过了)。这只是示例监督,还是不需要?我很好奇,因为 WaitHandle“封装了操作系统特定的对象”,因此很容易出现资源泄漏。
I've been reading up on .NET Threading and was working on some code that uses a ManualResetEvent. I have found lots of code samples on the internet. However, when reading the documentation for WaitHandle, I saw the following:
WaitHandle implements the Dispose
pattern. See Implementing Finalize and
Dispose to Clean Up Unmanaged
Resources.
None of the samples seem to call .Close() on the ManualResetEvent objects they create, even the nice Recursion and Concurrency article from the pfxteam blog (Edit - this has a using block I has missed). Is this just example oversight, or not needed? I am curious because a WaitHandle "encapsulates operating system–specific objects," so there could easily be a resource leak.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
最近,我收到了 Joseph Albahari、Ben Albahari 的C# 4.0 简而言之:权威参考的摘录。在第 834 页,第 21 章:线程中有一节讨论了这一点。
I was recently forwarded an excerpt from C# 4.0 in a Nutshell: The Definitive Reference By Joseph Albahari, Ben Albahari. On page 834, in Chapter 21: Threading there is a section talking about this.
一般来说,如果一个对象实现了
IDisposable
,那么它这样做是有原因的,您应该调用Dispose
(或Close
,视情况而定) )。在您站点的示例中,ManualResetEvent 包装在using
语句内,该语句将“自动”处理调用Dispose
。在这种情况下,Close
与Dispose
是同义的(在大多数提供Close
方法的IDisposable
实现中都是如此)。示例中的代码:
扩展为
In general, if an object implements
IDisposable
it is doing so for a reason and you should callDispose
(orClose
, as the case may be). In the example you site, the ManualResetEvent is wrapped inside ausing
statement, which will "automatically" handle callingDispose
. In this case,Close
is synonymous withDispose
(which is true in mostIDisposable
implementations that provide aClose
method).The code from the example:
expands to
Close 在 ManualResetEvent 的 Dispose 内部处理,并由“using”语句调用。
http://msdn.microsoft.com/en-我们/库/yh598w02%28VS.100%29.aspx
The Close is handled inside ManualResetEvent's Dispose, and that's called by the 'using' statement.
http://msdn.microsoft.com/en-us/library/yh598w02%28VS.100%29.aspx
您会注意到代码
使用“using”关键字。即使代码抛出异常,这也会在完成时自动调用 dispose 方法。
You'll notice the code
uses the 'using' keyword. This automatically calls the dispose method when finished even if the code throws an exception.
我经常使用
ManualResetEvent
并且认为我从未在单个方法中使用过它 - 它始终是类的实例字段。因此using()
通常不适用。如果您有一个作为
ManualResetEvent
实例的类实例字段,请让您的类实现IDisposable
并在您的Dispose()
方法中调用ManualResetEvent.Close()
。然后,在类的所有用法中,您需要使用using()
或使包含类实现IDisposable
并重复、重复...I've used
ManualResetEvent
a lot and don't think I've ever used it inside a single method--it's always an instance field of a class. Thereforeusing()
often does not apply.If you have a class instance field that is an instance of
ManualResetEvent
, make your class implementIDisposable
and in yourDispose()
method callManualResetEvent.Close()
. Then in all usages of your class, you need to useusing()
or make the containing class implementIDisposable
and repeat, and repeat...如果您将
ManualResetEvent
与匿名方法一起使用,那么它显然很有用。但正如 Sam 提到的,它们通常可以传递给工人,然后设置并关闭。所以我想说这取决于你如何使用它的上下文 - MSDN WaitHandle.WaitAll() 代码示例有一个很好的例子来说明我的意思。
下面是一个基于 MSDN 示例的示例,说明如何使用
using
语句创建 WaitHandles 会出现异常:If you're using a
ManualResetEvent
with anonymous methods then it's obviously useful. But as Sam mentioned they can often be passed around into workers, and then set and closed.So I would say it depends on the context of how you are using it - the MSDN WaitHandle.WaitAll() code sample has a good example of what I mean.
Here's an example based on the MSDN sample of how creating the WaitHandles with a
using
statement would exception: