获取对象处置/销毁的通知

发布于 2024-09-09 16:19:43 字数 319 浏览 2 评论 0原文

我需要一种方法来跟踪各种类的实例,而这些类不知道它们正在被跟踪。本质上,我有一个类工厂,它创建实例并将它们交给另一个线程。一旦该线程完成并卸载实例,我就需要收到通知,以便我可以进行引用计数,并在所有实例都消失时从类工厂退出。

挑战是我无法修改我将加载的任何类,因为我无法控制它们的源代码。

跟踪我创建的实例很简单,我可以在创建它们时将它们放入某种集合中。追踪他们的破坏给我带来了麻烦。如果我可以修改源代码,我会向每个类添加一个事件,当我创建一个实例时,我会挂钩该事件并将其用作我的通知。但我不能那样做。

所以,问题是:是否有一种偷偷摸摸的方法来监视对象实例并检测它何时被销毁?

I need a way to track instances of various classes, without those classes having any knowledge that they are being tracked. Essentially, I have a class factory which creates instances and hands them off to another thread. Once that thread completes and unloads the instance, I need to get notified of that so I can do reference counting and exit from my class factory when all the instances are gone.

The challenge is that I can't modify any of the classes I'll bve loading, because I don't control their source code.

Tracking the instances I create is simple, I can just put them in some sort of collection as I create them. Tracking their destruction is causing me problems. If I could modify the source code, I'd add an event to each class and when I create an instance, I'd hook into the event and use that as my notification. But I can't do that.

So, the question is this: is there a sneaky way to monitor an object instance and detect when it is being destroyed?

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

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

发布评论

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

评论(4

落花浅忆 2024-09-16 16:19:43

由于您正在创建对象,因此您似乎可以返回 Decorator 而不是实际实例。

通过使用装饰器模式,您可以将返回的对象“包装”在您自己的装饰API中。装饰可以提供 IDisposable 实现来提供销毁通知。

Since you're creating the objects, it seems like you could return a Decorator instead of the actual instance.

By using the Decorator Pattern, you could "wrap" the returned object in your own, decorated API. The decoration could provide an IDisposable implementation that provided your destruction notification.

人间不值得 2024-09-16 16:19:43

没有办法获得主动通知,但您可以保留对象的 WeakReference 并定期检查是否有任何对象已死亡。

编辑:我比我更喜欢里德的回答!

There isn't a way to get active notification, but you could keep a WeakReference to the objects and periodically check if any have died.

Edit: I like Reed's answer better than mine!

凉月流沐 2024-09-16 16:19:43

如果您保存对您创建的实例的引用列表,它们将不会被垃圾收集,因此永远不会被销毁...

相反,您可以创建一个包含 Guid 列表的存储库,并为每个实例创建一个新的 Guid,然后将其添加到列表中 - 类似 FactoryRepository 之类的东西。通过这种方式,您不会遇到垃圾收集的引用问题,因为 Guid 是结构而不是引用类型。然后,您可以从每个类继承来创建一个可以在销毁时发出通知的类型。我假设,由于您无法更改原始类的代码,因此您也无法更改这些类的使用者,因此诸如装饰器模式(通过接口)之类的东西已经消失,因为类型不兼容。

非常简单的例子:

public class OriginalClassDestroyNotifier : OriginalClass
{
    private readonly Guid _instanceId;

    public OriginalClassDestroyNotifier(Guid instanceId)
    {
        _instanceId = instanceId;
    }

    ~OriginalClassDestroyNotifier()
    {
        FactoryRepository.NotifyDestroyed(_instanceId);
    }
}

If you hold a list of the references to the instances you create they will not get garbage collected and so will never be destroyed...

Instead you can create a repository that holds a list of Guids and create a new Guid for each instance and then add it to a list instead - something like a FactoryRepository. In this way you do not have a reference problem for garbage collection as Guids are structs rather than reference types. You could then inherit from each class to create a type that can notify on destroy. I am assuming that as you cannot alter the code of the original classes, you cannot also alter the consumers of these classes, therefore something like the decorator pattern (via an interface) is out because the types would not be compatible.

Very simplified example:

public class OriginalClassDestroyNotifier : OriginalClass
{
    private readonly Guid _instanceId;

    public OriginalClassDestroyNotifier(Guid instanceId)
    {
        _instanceId = instanceId;
    }

    ~OriginalClassDestroyNotifier()
    {
        FactoryRepository.NotifyDestroyed(_instanceId);
    }
}
§普罗旺斯的薰衣草 2024-09-16 16:19:43

你如何控制对象的销毁:

public void Destroy(T obj)
{
    if (obj == null)
        throw new ArgumentNullException("obj");
    if (!_living.Contains(obj))
        throw new ArgumentException("Where did this obj come from?");

    using (obj as IDisposable)
    {

    }

    _living.Remove(obj); // List?
}

How about you control the destruction of the object:

public void Destroy(T obj)
{
    if (obj == null)
        throw new ArgumentNullException("obj");
    if (!_living.Contains(obj))
        throw new ArgumentException("Where did this obj come from?");

    using (obj as IDisposable)
    {

    }

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