在类退出时强制执行方法调用

发布于 2024-12-12 17:49:36 字数 271 浏览 0 评论 0原文

我有一个基类,当继承的任何类都会将 GUID 添加到另一个单例类的列表中。我希望基类中有一个方法,当继承的类完成执行时,该方法将从列表中删除 GUID。我正在考虑将方法调用放入 Dispose 方法中,但不确定这是否是正确的方法,因为我希望尽快进行删除 GUID 的方法调用,所以我不想等待.NET GC 开始工作。另外,由于我以前从未实现过 Dispose,我可以只将 IDisposable 接口添加到我的基类中并创建一个包含 GUID 删除逻辑的 Dispose 方法,还是必须在 Dispose 方法中显式包含其他逻辑?

I have a base class that when any class inherited from will add a GUID to a list in another singleton class. I want to have a method in the base class that will remove the GUID from the list when the inherited class has completed its execution. I was looking at putting a method call in a Dispose method but wasn't sure if this was the right way to go as I want the method call to remove the GUID to happen as soon as possible so I did not want to wait for the .NET GC to begin it's work. Also as I have never implemented Dispose before can I just add the IDisposable interface to my base class and create a Dispose method that includes the GUID removal logic or do you have to explicitly include other logic in a Dispose method?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

指尖上的星空 2024-12-19 17:49:36

编写 Dispose 方法并没有什么神奇之处。它与任何其他方法没有什么不同。如果您不调用它,系统将不会为您执行此操作。

例外:

如果您确实想确保正确清理这些宝贵的资源,那么您还需要为 GC 到达您的对象时的情况构建一些保护措施,即使 Dispose 方法没有以通常的方式调用。

执行此操作的方法是从对象析构函数中调用它,并且在执行此操作时需要注意一些事项。首先,当 Dispose 从析构函数运行时,它发生在与应用程序主线程不同的线程上。此外,此时您的对象引用的任何对象可能已被收集,您也无法使用它们。

There is no magic in writing the Dispose method. It is no different from any other method. If you do not call it the system will not do it for you.

EXCEPT:

If you really want to make sure that those precious resources are cleaned up properly, you also need to build some safeguards for the situations when the GC gets to your object even though the Dispose method was not called in a usual way.

The way to do it is to also call it from the object destructor and as you do it there are a few things to watch out. First of all when the Dispose runs from the destructor it happens on a thread different from the main thread of your app. Also you cannot use any of the objects your object references by this time they might'of been collected.

剧终人散尽 2024-12-19 17:49:36

实际上,你正在混合东西。

垃圾收集器永远不会在您的类上调用Dispose。您应该实现 IDisposable 以便客户端能够确保始终调用 cleanup 方法:

using System;

class BaseClass : IDisposable {
    bool _guidremoved = false;
    public void RemoveGuid() {
        if (!_guidremoved) {
            _guidremoved = true;
            // your logic here                
        }
    }
    public void Dispose() {
        RemoveGuid();
    }
}

class Derived : BaseClass { 
}

static class Program {
    static void Main(string[] args) {
        using (Derived d = new Derived()) { 
            // do stuff here...

            // call RemoveGuid explicitly, if needed
            d.RemoveGuid();
        } // when we exit this block, Dispose is called
    }
}

在此示例中,using 块确保 RemoveGuid如果未到达包含 d.RemoveGuid() 的行,则由 Dispose() 调用该方法。

相反,垃圾收集器会在运行时调用类的析构函数(或者更好的是 Finalize 方法),但这可能不是在您的情况下删除 GUID 的正确位置。

检查实施 Finalize 和 Dispose 以清理非托管资源< /a> 了解更多详细信息。

You are mixing things, actually.

The garbage collector will never call Dispose on your class. You should implement IDisposable so that a client can ensure that the cleanup method is always called:

using System;

class BaseClass : IDisposable {
    bool _guidremoved = false;
    public void RemoveGuid() {
        if (!_guidremoved) {
            _guidremoved = true;
            // your logic here                
        }
    }
    public void Dispose() {
        RemoveGuid();
    }
}

class Derived : BaseClass { 
}

static class Program {
    static void Main(string[] args) {
        using (Derived d = new Derived()) { 
            // do stuff here...

            // call RemoveGuid explicitly, if needed
            d.RemoveGuid();
        } // when we exit this block, Dispose is called
    }
}

In this example, the using block ensures that the RemoveGuid method is called by Dispose() if the line with d.RemoveGuid() is not reached.

The garbage collector would, instead, call the destructor (or better, the Finalize method) on your class when it runs, but that would probably not be the proper place to remove the GUID in your case.

Check Implementing Finalize and Dispose to Clean Up Unmanaged Resources for more details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文