Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取对象处置/销毁通知_C#_.net_Clr_Object Lifetime - Fatal编程技术网

C# 获取对象处置/销毁通知

C# 获取对象处置/销毁通知,c#,.net,clr,object-lifetime,C#,.net,Clr,Object Lifetime,我需要一种方法来跟踪各种类的实例,而不让这些类知道它们正在被跟踪。本质上,我有一个类工厂,它创建实例并将它们交给另一个线程。一旦该线程完成并卸载实例,我需要得到通知,这样我就可以进行引用计数,并在所有实例都消失后退出类工厂 挑战在于,我不能修改任何要加载的类,因为我无法控制它们的源代码 跟踪我创建的实例很简单,我可以在创建它们时将它们放在某种集合中。追踪他们的破坏给我带来了麻烦。如果我可以修改源代码,我会在每个类中添加一个事件,当我创建一个实例时,我会挂接到事件中并将其用作通知。但我不能那样做

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

挑战在于,我不能修改任何要加载的类,因为我无法控制它们的源代码

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


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

如何控制对象的销毁:

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?
}

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


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

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


编辑:我更喜欢里德的答案

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

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

非常简单的示例:

public class OriginalClassDestroyNotifier : OriginalClass
{
    private readonly Guid _instanceId;

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

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

+1这很有趣-我一直在想同样的事情,直到我读到他说他在控制物体构造的部分;)在我的情况下,这看起来可能是最可行的解决方案,我将尝试一下。我更喜欢你的,而不是里德的,因为这意味着这些类型的客户不需要知道特殊的装饰类型。这很好。您可以使用refection生成要修改的装饰器。如果班级规模很大,这将非常重要。这非常有趣,我将继续跟进。谢谢。那么什么叫Destroy()?请记住,我无法控制正在加载的类型(事实上,它们是从文件夹中动态加载的,我事先不知道会在那里找到什么)。