【问题标题】:Get notification of object disposal/destruction获取对象处置/销毁的通知
【发布时间】:2010-07-16 18:30:05
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: c# .net clr object-lifetime


    【解决方案1】:

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

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

    【讨论】:

    • 这很好。您可以使用反射来生成装饰器。如果班级人数众多,这将很重要。
    • 这很有趣,我会跟进。谢谢。
    【解决方案2】:

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

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

    【讨论】:

    • +1 这很有趣 - 我一直在想同样的事情,直到我读到他说他正在控制对象的构造的部分;)
    • 这实际上看起来可能是在我的情况下最可行的解决方案,我将尝试一下。
    • 我比 Reed 更喜欢你的,因为这意味着这些类型的客户不需要了解特殊的装饰器类型
    【解决方案3】:

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

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

    非常简单的例子:

    public class OriginalClassDestroyNotifier : OriginalClass
    {
        private readonly Guid _instanceId;
    
        public OriginalClassDestroyNotifier(Guid instanceId)
        {
            _instanceId = instanceId;
        }
    
        ~OriginalClassDestroyNotifier()
        {
            FactoryRepository.NotifyDestroyed(_instanceId);
        }
    }
    

    【讨论】:

      【解决方案4】:

      你控制对象的销毁怎么样:

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

      【讨论】:

      • 那么什么叫 Destroy()?请记住,我无法控制我正在加载的类型(实际上它们是从文件夹中动态加载的,我事先不知道我会在那里找到什么)。
      猜你喜欢
      • 1970-01-01
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多