首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我能否检测一个对象是否调用了GC.SuppressFinalize?

我能否检测一个对象是否调用了GC.SuppressFinalize?
EN

Stack Overflow用户
提问于 2011-01-08 15:50:08
回答 3查看 715关注 0票数 3

是否有一种检测对象是否调用GC.SuppressFinalize的方法?

我有一个类似于这样的对象(为了清晰起见,删除了完整的处理模式):

代码语言:javascript
复制
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有方法来设置对象的可终结性(SuppressFinalizeReRegisterForFinalize),但我没有看到任何方法来获得对象的可终结性。除了购买Typemock或编写我自己的CLR主机之外,是否有任何方法来询问在给定实例上是否调用了GC.SuppressFinalize?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-13 15:39:26

如果您想确认如果您的对象不拥有资源,那么终结器是否已被抑制,那么您可以让终结器断言它拥有资源?测试必须执行GC.Collect和GC.WaitForPendingFinalizers,但是生产代码除了断言(可以从生产构建中省略)之外没有任何额外的内容。断言有一个小小的警告:如果创建对象的线程在创建对象和设置所有权状态之间死亡,终结器可能会不适当地运行。

话虽如此,我不知道是否最好有一个抽象的ResourceWrapper类型,它有单独的子类型OwnedResourceWrapper和SharedResourceWrapper,它拥有或不拥有所讨论的资源。这样,不拥有资源的子类型一开始就不需要有终结器。请注意,对于SharedResourceWrapper来说,将IDisposable实现为非op可能是有用的。

票数 3
EN

Stack Overflow用户

发布于 2011-01-08 16:16:49

这是不可能的,GC只是没有提供这些信息。这是一个很好的理由,对象不只是处于两种状态。它也可能已经在终结队列中,也可能已经完成。

定制的CLR主机不会帮助您,宿主界面不会为gc提供任何钩子。您只需在终结器中检查SuppressFinalize是否已被调用时,就可以检查它是否已被调用。(快速)记录它。你不能证明相反的。

Fwiw,.NET框架类不会这样做,它们只是让终结器运行。

票数 4
EN

Stack Overflow用户

发布于 2011-01-08 16:22:14

这可能会有所帮助(简化荒谬)。一个技巧是在终结器中做一些日志(这可能是一个静态的状态),如果有人缺席,他已经调用了抑制终结,但你仍然不能确定什么时候。

如果您是该类型的作者,则此操作有效。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4634671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档