如若"配置"只可用于含非托管资源类型? [英] Should "Dispose" only be used for types containing unmanaged resources?

查看:124
本文介绍了如若"配置"只可用于含非托管资源类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近有关于的Dispose 和实现类型的IDisposable 。<价值与同事讨论/ p>

我觉得这是在实施的IDisposable 为应清理各类尽快,即使没有非托管资源清理

我的同事认为,不同的;实施的IDisposable 如果你没有任何非托管资源为你的类型,最终会被垃圾收集是没有必要的。

我的观点是,如果你有一个ADO.NET连接,你想使用新的,然后实施的IDisposable 尽快关闭MyThingWithAConnection()将使意义。我的同事回答说,在幕后,ADO.NET连接是一个非托管资源即可。我给他的答复的答复是,一切终究是一个非托管资源

我知道href=\"http://msdn.microsoft.com/en-us/library/b1yfkh5e%28v=vs.71%29.aspx\">建议哪里您免费托管和非托管资源,如果的Dispose 被称为,但如果通过终结/析构函数(名为唯一的免费非托管资源和博客前一阵子关于如何提醒消费者的)

所以,我的问题是,如果你有一个不包含非托管资源的类型,是否值得实施的IDisposable


解决方案

有用于的IDisposable 不同的有效使用。一个简单的例子拿着一个打开的文件,你必须为你不需要任何更多的在某一时刻尽快关闭。当然,你可以提供的方法关闭,但有它在部署和使用模式,比如将更加异常安全的。

>

一个比较流行的例子是抱着一些其他的的IDisposable 资源,这通常意味着你需要提供你自己的的Dispose 为了处理它们。

在一般情况下,只要你想有任何的破坏确定性,需要实现的IDisposable

我的观点和你之间的区别是,我执行的IDisposable 只要一些资源需求的确定的破坏/释放,没有必要的尽快的。依靠垃圾收集是不是在这种情况下的一个选项(与你的同事的说法),因为它发生在时间未predictable时刻,实际上可能根本不会发生!

这是任何资源的掩护下,非托管的事实确实并不意味着什么:开发商应该考虑在何时以及如何正确处理此对象的术语而不是它是如何的掩护下工作。底层的实现可能会反正时间而改变。

事实上,C#和C ++之间的主要区别之一就是没有违约确定性的破坏。在的IDisposable 来缩小差距:您可以订购确定性毁灭(虽然你不能保证客户端调用它;在C ++中,你无法确定相同的方式,客户端叫删除的对象)。


小加法:什么是真正之间的差别的确定的释放资源并尽快释放他们的尽可能的?实际上,这些是不同的(尽管不是完全正交)的概念。

如果资源被释放的确定性的,这意味着客户端code应该有一个可能性,说:现在,我想这个资源中解脱出来。这可能是实际上并不是尽早的时刻,当该资源可以被释放:保持该资源的对象可能已完成了从资源所需要的一切,所以潜在地可能已经释放资源。在另一方面,对象可能选择保留(通常非托管)资源甚至对象的物后通过跑,仅在终结清洗起来(如果保持对资源太长的时间没有任何问题)。

因此​​,尽快释放资源的可能的,严格来说,的Dispose 是没有必要的:对象可以尽快释放资源因为它实现了自身的资源不需要任何更多。然而的Dispose 作为一个有用的提示,对象的本身的不需要任何更多的,所以也许资源的可能的在这一点上,如果合适的释放。


还有一个必要的补充:这不仅是需要确定性释放非托管资源!这似乎是在这个问题的答案中的观点的差的关键点之一。一个可以具有纯粹想象力构建体,其可需要被确定性地释放。

例子是:访问某个共享结构(认为<一权href=\"http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx\">RW-lock),一个巨大的内存块(想象一下,你是手动管理的一些程序的内存),使用其他程序的许可证(想象一下,你是不是允许运行不止的 X 的同时一些程序的副本)等在这​​里被释放的对象不是非托管资源,而是一个的右键的做/使用的东西,这是一个纯粹的内部构造程序逻辑。


小加法:这里是整齐的例子小清单[AB]使用的IDisposable :<一href=\"http://www.introtorx.com/Content/v1.0.10621.0/03_LifetimeManagement.html#IDisposable\">http://www.introtorx.com/Content/v1.0.10621.0/03_LifetimeManagement.html#IDisposable.

I was having a discussion with a colleague recently about the value of Dispose and types that implement IDisposable.

I think there is value in implementing IDisposable for types that should clean up as soon as possible, even if there are no unmanaged resources to clean up.

My colleague thinks differently; implementing IDisposable if you don't have any unmanaged resources isn't necessary as your type will eventually be garbage collected.

My argument was that if you had an ADO.NET connection that you wanted to close as soon as possible, then implementing IDisposable and using new MyThingWithAConnection() would make sense. My colleage replied that, under the covers, an ADO.NET connection is a unmanaged resource. My reply to his reply was that everything ultimately is an unmanaged resource.

I am aware of the recommended disposable pattern where you free managed and unmanaged resources if Dispose is called but only free unmanaged resources if called via the finalizer/destructor (and blogged a while ago about how to alert consumers of improper use of your IDisposable types)

So, my question is, if you've got a type that doesn't contain unmanaged resources, is it worth implementing IDisposable?

解决方案

There are different valid uses for IDisposable. A simple example is holding an open file, which you need to be closed at certain moment, as soon as you don't need it any more. Of course, you could provide a method Close, but having it in Dispose and using pattern like using (var f = new MyFile(path)) { /*process it*/ } would be more exception-safe.

A more popular example would be holding some other IDisposable resources, which usually means that you need to provide your own Dispose in order to dispose them as well.

In general, as soon as you want to have deterministic destruction of anything, you need to implement IDisposable.

The difference between my opinion and yours is that I implement IDisposable as soon as some resource needs deterministic destruction/freeing, not necessary as soon as possible. Relying on garbage collection is not an option in this case (contrary to your colleague's claim), because it happens at unpredictable moment of time, and actually may not happen at all!

The fact that any resource is unmanaged under the cover really doesn't mean anything: the developer should think in terms of "when and how is it right to dispose of this object" rather than "how does it work under the cover". The underlying implementation may change with the time anyway.

In fact, one of the main differences between C# and C++ is the absence of default deterministic destruction. The IDisposable comes to close the gap: you can order the deterministic destruction (although you cannot ensure the clients are calling it; the same way in C++ you cannot be sure that the clients call delete on the object).


Small addition: what is actually the difference between the deterministic freeing the resources and freeing them as soon as possible? Actually, those are different (though not completely orthogonal) notions.

If the resources are to be freed deterministically, this means that the client code should have a possibility to say "Now, I want this resource freed". This may be actually not the earliest possible moment when the resource may be freed: the object holding the resource might have got everything it needs from the resource, so potentially it could free the resource already. On the other hand, the object might choose to keep the (usually unmanaged) resource even after the object's Dispose ran through, cleaning it up only in finalizer (if holding the resource for too long time doesn't make any problem).

So, for freeing the resource as soon as possible, strictly speaking, Dispose is not necessary: the object may free the resource as soon as it realizes itself that the resource is not needed any more. Dispose however serves as a useful hint that the object itself is not needed any more, so perhaps the resources may be freed at that point if appropriate.


One more necessary addition: it's not only unmanaged resources that need deterministic deallocation! This seems to be one of key points of the difference in opinions among the answers to this question. One can have purely imaginative construct, which may need to be freed deterministically.

Examples are: a right to access some shared structure (think RW-lock), a huge memory chunk (imagine that you are managing some of the program's memory manually), a license for using some other program (imagine that you are not allowed to run more than X copies of some program simultaneously), etc. Here the object to be freed is not an unmanaged resource, but a right to do/to use something, which is a purely inner construct to your program logic.


Small addition: here is a small list of neat examples of [ab]using IDisposable: http://www.introtorx.com/Content/v1.0.10621.0/03_LifetimeManagement.html#IDisposable.

这篇关于如若&QUOT;配置&QUOT;只可用于含非托管资源类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆