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

C# 存储与对象关联的元数据的正确方法?,c#,caching,memory-leaks,metadata,C#,Caching,Memory Leaks,Metadata,首先,我担心内存泄漏问题。因为我所做的是使用一些字典来存储元数据,其中包含对象本身的键。因此,我可以通过传入对象来查找元数据(应该是动态的) 请注意,此处的对象没有任何帮助标识自身的GUID,标识对象的唯一方法是通过其实例。 这种存储与WPF中的DependencyObject非常相似。我们可以声明dependencProperty(附加属性)来扩展DependencyObject(元数据包含在附加属性中) 以下是我所拥有的: Dictionary<object, SomeMetaData

首先,我担心内存泄漏问题。因为我所做的是使用一些字典来存储元数据,其中包含对象本身的键。因此,我可以通过传入对象来查找元数据(应该是动态的)

请注意,此处的对象没有任何帮助标识自身的GUID,标识对象的唯一方法是通过其实例。 这种存储与WPF中的
DependencyObject
非常相似。我们可以声明
dependencProperty
(附加属性)来扩展
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);
Dictionary\u metadataLookup=newdictionary();
//存储元数据
_metadataLookup[someObject]=someMetaData;
//获取元数据
有些元数据有些元数据;
_TryGetValue(someObject,out someMetaData);
如果
someObject
的生存期与使用
\u metadataLookup
的作用域的生存期相同,则可以。但是如果
someObject
(存储在
\u metadataLookup
中后)应该被销毁(逻辑上变得未使用),该怎么办?我们还必须手动将其从metadataLookup中删除,否则会出现内存泄漏


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

为此,您可以使用

公共类示例
{
公共静态void Main()
{
var mc1=新的ManagedClass();
var mc2=新的ManagedClass();
var mc3=新的ManagedClass();
var cwt=new ConditionalWeakTable();
Add(mc1,newclassdata());
Add(mc2,newclassdata());
Add(mc3,newclassdata());
var wr2=新的WeakReference(mc2);
mc2=null;
GC.Collect();
ClassData数据=null;
如果(wr2.Target==null)
WriteLine(“不存在对mc2的强引用”);
否则如果(cwt.TryGetValue(mc2,输出数据))
WriteLine(“在{0}创建的数据”,Data.CreationTime);
其他的
Console.WriteLine(“表中未找到mc2”);
}
}
公共类ManagedClass
{ 
}
公共类类数据
{
公共日期时间创建时间;
公共对象数据;
公共类数据()
{
CreationTime=DateTime.Now;
this.Data=新对象();
}
}
//该示例显示以下输出:
//不存在对mc2的强引用。

是的,存储引用可能不是一件好事。但是,您可以存储hashcode,尽管您必须实现它properly@TheGeneral谢谢,您确定散列代码可以帮助识别对象而不产生任何争用吗?谢谢您,看起来
ConditionalWeakTable
是编译器服务的工具。在我们自己的代码中使用它可以吗?我担心将来会发生变化。还有一件事我想在这里是这个
条件可扩展表的一些并发版本
?是的,实际上在我的场景中,我可能需要同时查找数据。不管怎么说,这个答案很好,但我还是把这个问题留了一段时间。再次感谢。@无可救药,正如文档所说:ConditionalWeakTable类的实例是线程安全的。他们不需要呼叫者做任何额外的锁定。@无望很难说,这是好还是不好。但是
ConditionalWeakTable
似乎适合您描述的情况谢谢,至少我没有其他方法,也许有人会研究WPF的源代码以实现
DependencyObject
,而
dependencProperty
将提供另一种解决方案。
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.