存储与对象关联的某些元数据的正确方法?
The correct way to store some metadata associated with an object?
首先我担心这里的内存泄漏问题。因为我所做的是使用一些 Dictionary 来存储元数据和对象本身的 Key。所以我可以通过传入对象来查找元数据(应该是动态的)。
请注意,此处的对象没有任何 GUID 来帮助识别自身,识别它的唯一方法是通过其实例。
这种存储看起来很像 WPF 中 DependencyObject
中的内容。我们可以声明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);
如果 someObject
的生命周期与使用 _metadataLookup
的作用域的生命周期相同就好了。但是,如果 someObject
(存储在 _metadataLookup
中)应该被销毁(逻辑上变为未使用)怎么办?我们也必须手动将其从 _metadataLookup
中删除,否则那里会发生内存泄漏。
我正在为这个问题寻求更好的解决方案,出乎意料地忘记手动删除对象或者根本不知道何时应该删除对象是这里的问题。谢谢。
为此,您可以使用 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.
首先我担心这里的内存泄漏问题。因为我所做的是使用一些 Dictionary 来存储元数据和对象本身的 Key。所以我可以通过传入对象来查找元数据(应该是动态的)。
请注意,此处的对象没有任何 GUID 来帮助识别自身,识别它的唯一方法是通过其实例。
这种存储看起来很像 WPF 中 DependencyObject
中的内容。我们可以声明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);
如果 someObject
的生命周期与使用 _metadataLookup
的作用域的生命周期相同就好了。但是,如果 someObject
(存储在 _metadataLookup
中)应该被销毁(逻辑上变为未使用)怎么办?我们也必须手动将其从 _metadataLookup
中删除,否则那里会发生内存泄漏。
我正在为这个问题寻求更好的解决方案,出乎意料地忘记手动删除对象或者根本不知道何时应该删除对象是这里的问题。谢谢。
为此,您可以使用 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.