在C#中处理字典的最佳实践

18

我在我的会话类中有一个ConcurrentDictionary。
键是代表管理器类的接口。
值是用于该管理器在此会话中使用的DataContract类列表。

当我处置会话类时,我希望清除这个字典。我需要清除所有的值和键,但我不能处理这些键——因为它们在类处置后仍然存在。

这样做足够了吗?这会让GC来完成工作吗?

_myDictionary = null;

或者我需要使用 foreach 迭代所有键,并使用 Remove 方法清除值。


那就够了。但是,如果除字典以外的任何东西仍然引用这些值,那么当这些其他引用消失时,这些值才会被释放。 - Matthew Watson
1个回答

26
当我处理session类时,我希望清除这个字典。为什么?如果该session实例将变得适合进行垃圾回收,并且session是唯一引用字典的对象,则该字典也将变得适合进行垃圾回收。 这几乎肯定是不必要的。如果其他任何东西都引用字典,则将该变量设置为null将不起作用。如果没有其他东西引用字典,并且session将变得适合进行垃圾回收,则根本不需要这样做。 唯一值得将变量设置为空以进行垃圾回收的时间是当该变量本身将继续存在时(例如,它是不会被垃圾回收的对象中的实例变量,或者它是静态变量)。 请注意,垃圾收集完全与“处理”对象无关。Dispose和IDisposable通常涉及未受管控的资源,在您的问题中没有表明该概念相关。

由于字典是托管资源,当处理会话类时,它将自动进行垃圾回收?没有其他类持有对此字典的引用,但某个键/值集合的键是对一个类的引用,该类将在会话暴露后继续存在,因此我不确定这是否会干扰处理。而且,该类实现了最佳实践模式IDisposable。 - ilansch
1
@ilansch:再次强调,Dispose和垃圾回收是两个不同的概念。如果没有任何变量引用该Session实例,那么该Session实例可以被垃圾回收器回收。即使某个键没有被垃圾回收,也不会影响字典的垃圾回收 - 这种关系不是从键到字典的,而是相反的。 - Jon Skeet
1
好的,谢谢回复。我的困惑在于我在这个会话中还持有一个回调委托作为私有成员,当会话被处理时,必须将此委托设置为null。否则,从会话到长期存在的类仍然存在引用。 - ilansch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接