存储与对象关联的元数据的正确方法?

Hop*_*ess 0 c# caching memory-leaks metadata

首先,我担心这里的内存泄漏问题.因为我所做的是使用一些Dictionary来存储元数据与对象本身的Key.所以我可以通过传入对象来查找元数据(应该是动态的).

请注意,此处的对象没有任何GUID来帮助标识自身,识别它的唯一方法是通过其实例.这种存储看起来很像DependencyObjectWPF中的内容.我们可以声明DependencyProperty(附加属性)来扩展DependencyObject(元数据包含在附加属性中).

这是我有的:

Dictionary<object, SomeMetaData> _metadataLookup = new Dictionary<object,SomeMetaData>();
//to store metadata
_metadataLookup[someObject] = someMetaData;
//to get metadata
SomeMetaData someMetaData;
_metadataLookup.TryGetValue(someObject, out someMetaData);
Run Code Online (Sandbox Code Playgroud)

如果someObject生命周期与使用范围的生命周期相同,那就没问题了_metadataLookup.但是如果someObject(存储之后_metadataLookup)应该销毁(逻辑上变为未使用)会怎么样?我们也必须手动将其删除_metadataLookup,否则会出现内存泄漏.

我正在寻找一个更好的解决方案来解决这个问题,意外地忘记手动删除对象或者根本不知道何时应该删除对象是一个问题.谢谢.

Bac*_*cks 7

为此,您可以使用ConditionalWeakTable

public class Example
{
   public static void Main()
   {
      var mc1 = new ManagedClass();
      var mc2 = new ManagedClass();
      var mc3 = new ManagedClass();

      var cwt = new ConditionalWeakTable<ManagedClass, ClassData>();
      cwt.Add(mc1, new ClassData());          
      cwt.Add(mc2, new ClassData());
      cwt.Add(mc3, new ClassData());

      var wr2 = new WeakReference(mc2);
      mc2 = null;

      GC.Collect();

      ClassData data = null; 

      if (wr2.Target == null)
          Console.WriteLine("No strong reference to mc2 exists.");   
      else if (cwt.TryGetValue(mc2, out data))
          Console.WriteLine("Data created at {0}", data.CreationTime);      
      else
          Console.WriteLine("mc2 not found in the table.");
   }
}

public class ManagedClass
{ 
}

public class ClassData
{
   public DateTime CreationTime;
   public object Data;   

   public ClassData()
   {
      CreationTime = DateTime.Now;
      this.Data  = new object();     
   }
}
// The example displays the following output:
//       No strong reference to mc2 exists.
Run Code Online (Sandbox Code Playgroud)