是否可以确定在最后一个对象引用被释放后正在处理的对象?

时间:2014-10-01 17:31:46

标签: c# .net garbage-collection destructor

我正在创建一个包装堆对象的Memory holder类,我想这样做 确定对象的处理对GC非常有用。

我想要类似的东西:

myObj = null; //Immediately call to ~myObj()

3 个答案:

答案 0 :(得分:2)

不,你不能这样做。您应该只使用IDisposable,因为它意味着要使用。

答案 1 :(得分:2)

.NET框架和运行时为使用非托管资源的应用程序提供了两个功能。

  1. 确定性清理IDisposable接口允许代码通过显式或隐式调用Dispose()方法在特定时间释放资源。 (C#中的using语句为此调用提供了隐式支持。)
  2. 最终清理:如果用户无法通过调用Dispose()方法释放非托管资源,则可以使用终结器来防止长时间运行的应用程序随着时间的推移而泄漏这些资源。用户代码通常不应包含用户定义的终结器;相反,创建(或使用现有的)扩展SafeHandle的类并实现ReleaseHandle方法来定义发布行为。
  3. 请注意,IDisposable.Dispose()是确定资源清理的唯一支持机制。最终的清理是一个应该避免的非确定性后备。

答案 2 :(得分:0)

COM对象期望在超出范围时立即得到通知,但除了通过Dispose之外,.NET不支持提示通知。你应该在你的dispose方法中调用IUnknown.Release,但在调用IUnknown.Release之前必须确保,任何人都不可能尝试再次使用该COM对象。尝试使用Release之后的COM对象,或者甚至只是尝试再次调用Release,这是一种灾难。

因此,我建议不要将对COM本身的引用发布到外部代码中。相反,让持有对象的类将所有对对象本身的请求转发到锁内(以确保代码不会尝试同时访问),并让Dispose方法获取锁,调用{{1}在对象上,然后使引用无效。任何未来操作对象的任何尝试都不会被捕获将导致Release不是很好,但仍然比在释放后使用NullReferenceException对象更好。