清除收藏集 - 首先清除每个项目,或者一次清除所有项目?

时间:2009-05-28 16:21:06

标签: .net list collections dictionary

假设我有一个本身包含集合的某种集合;例如,Dictionary(Of String,List(Of MyClass))。如果我想完全清除Collection,在清除父集合之前清除每个子集合是否有意义,如下所示:

For Each ListDef As KeyValuePair(Of String, List(Of MyClass)) In MasterDictionary
    Dim ThisList As List(Of MyClass) = ListDef.Value
    ThisList.Clear()
Next

MasterDictionary.Clear()

或者这真的只是简单地完成:

MasterDictionary.Clear()

我问是否有任何理由 - 性能,安全性,清晰度等 - 使用第一种方法。我通常自己使用第二种方法,因为我假设它隐含地实现了第一种方法所做的事情。但我们都知道有时候会有多危险;因此这个问题。

编辑:今天,在我自己的应用程序中,我看到了令人信服的证据,证明在某些情况下第一种方法可能更合适。在我的应用程序中,我有一些全局集合(包含列表的字典,如上面的示例代码中所示),当用户单击标记为“加载数据”的按钮时,该集合将被填充。当用户单击“卸载数据”以从头开始时,我以前使用上面的第二种方法清除这些集合。

问题是,当用户第二次点击“加载数据”时,应用程序会突然变得很慢。最终它会再次填充收藏品,但是以蜗牛的速度完成。直到我终于尝试了上面的第一种方法,我才弄清楚如何解决这个问题。现在重新加载和重新填充集合的工作速度与第一次加载它们的速度一样快。

根据到目前为止发布的答案,听起来我必须在某处“引入儿童馆藏的其他代码”;然而,它并不像我一样对待我。我引用这些孩子的唯一地方就是我对他们父母进行迭代的地方;如果父母被清除,那么他们应该没有代码所知的孩子,对吗?

希望有人可以帮助我理解这些引用是如何仍然挥之不去,或者我正在忽略的是什么。

3 个答案:

答案 0 :(得分:4)

在这两种情况下,您都不会处理子集合中包含的单个元素的任何处理问题。在这种情况下,两者应该是相同的。

如果其他代码直接引用任何单个子集合,那么会产生差异的地方。如果在另一部分代码中保存对List(Of MyClass)之一的引用,则第一种方法将清除列表中的元素(并影响其他代码)。第二种方法不会这样做,因为它会单独留下List。

如果没有其他引用,则第二种方法只是等待GC清理元素。在两种情况下,GC都会处理各个引用,因此性能差异可以忽略不计。就个人而言,我会使用第二种方法,因为我认为它更清晰(并且更容易编写),并且在大多数情况下效果会不那么令人惊讶,特别是如果你在其他地方使用列表。

答案 1 :(得分:2)

如果没有其他对'child'集合的引用,那么'parent'集合上的Clear()将导致子集合(以及扩展中的项目)被清理 - 最终。只要没有子集合的元素实现IDisposable,我就说你是安全的,因为这意味着他们有一些资源被锁定,而且没有正确处理它们可能会导致问题。

答案 2 :(得分:1)

这取决于您的代码的使用方式。

如果你有其他代码引用任何List(Of MyClass),那么很明显,那些列表将使用第一种方法对其他代码为空,而在第一种方法中则不是这种情况。 / p>

如果有任何性能差异,我不知道,我想最好的方法是尝试对其进行分析。有人可能会认为第一种方法最初会使用更多的CPU功率,但在GC轮次期间可能会更少 - 但实际上这是分析有意义的情况:)。