是否有一种检测对象是否调用GC.SuppressFinalize的方法?
我有一个类似于这样的对象(为了清晰起见,删除了完整的处理模式):
public class ResourceWrapper {
private readonly bool _ownsResource;
private readonly UnmanagedResource _resource;
public ResourceWrapper(UnmanagedResource resource, bool ownsResource) {
_resource = resource;
_ownsResource = ownsResource;
if (!ownsResource)
GC.SuppressFinalize(this);
}
~ResourceWrapper() {
if (_ownsResource)
// clean up the unmanaged resource
}
}如果ownsResource构造函数参数是false,那么终结器就没有什么可做的了--因此从构造函数中调用GC.SuppressFinalize似乎是合理的(如果有点奇怪的话)。但是,由于这种行为很古怪,我很想在XML文档注释中注意到.如果我想评论它,那么我应该为它写一个单元测试。
但是,虽然System.GC有方法来设置对象的可终结性(SuppressFinalize,ReRegisterForFinalize),但我没有看到任何方法来获得对象的可终结性。除了购买Typemock或编写我自己的CLR主机之外,是否有任何方法来询问在给定实例上是否调用了GC.SuppressFinalize?
发布于 2011-01-13 15:39:26
如果您想确认如果您的对象不拥有资源,那么终结器是否已被抑制,那么您可以让终结器断言它拥有资源?测试必须执行GC.Collect和GC.WaitForPendingFinalizers,但是生产代码除了断言(可以从生产构建中省略)之外没有任何额外的内容。断言有一个小小的警告:如果创建对象的线程在创建对象和设置所有权状态之间死亡,终结器可能会不适当地运行。
话虽如此,我不知道是否最好有一个抽象的ResourceWrapper类型,它有单独的子类型OwnedResourceWrapper和SharedResourceWrapper,它拥有或不拥有所讨论的资源。这样,不拥有资源的子类型一开始就不需要有终结器。请注意,对于SharedResourceWrapper来说,将IDisposable实现为非op可能是有用的。
发布于 2011-01-08 16:16:49
这是不可能的,GC只是没有提供这些信息。这是一个很好的理由,对象不只是处于两种状态。它也可能已经在终结队列中,也可能已经完成。
定制的CLR主机不会帮助您,宿主界面不会为gc提供任何钩子。您只需在终结器中检查SuppressFinalize是否已被调用时,就可以检查它是否已被调用。(快速)记录它。你不能证明相反的。
Fwiw,.NET框架类不会这样做,它们只是让终结器运行。
发布于 2011-01-08 16:22:14
这可能会有所帮助(简化荒谬)。一个技巧是在终结器中做一些日志(这可能是一个静态的状态),如果有人缺席,他已经调用了抑制终结,但你仍然不能确定什么时候。
如果您是该类型的作者,则此操作有效。
https://stackoverflow.com/questions/4634671
复制相似问题