收集被修改;枚举操作可能无法执行。错误

时间:2011-08-04 15:21:33

标签: .net asp.net vb.net

我们有一些第三方代码由于抛出上述错误而导致一些痛苦:它有点奇怪,因为它是间歇性错误。以下是导致此问题的方法:

    Private Shared Sub IntLocateDictionaries(ByVal haystack As ExpDictionary, 
        ByVal needlearray() As Object, _
        ByVal resultarray() As Object, ByVal removemarks As Boolean)

        Dim i As Integer
        Dim item As Object

        For i = 0 To UBound(needlearray)
            If haystack.Exists(needlearray(i)) Then
                resultarray(i)(CStr(resultarray(i).Count + 1)) = haystack
                If removemarks Then
                    ExpandIT.FileLogger.LogError("*********** REMOVING From HAYSTACK - COULD CAUSE EXCEPTION! ***************")
                    haystack.Remove(needlearray(i))
                End If
            End If
        Next

        ' Scan for sub dictionaries
        For Each item In haystack.Values
            If TypeName(item) = "ExpDictionary" Then 
                IntLocateDictionaries(item, needlearray, resultarray, removemarks)
            End If
        Next
    End Sub

...这就是主叫行:

        currencyproducts = New ExpDictionary
        priceproducts = New ExpDictionary
        IntLocateDictionaries(info, New Object() {"_cc", "_csp"}, New Object() {currencyproducts, priceproducts}, False)

据我所知,这个错误通常是在枚举周围时尝试修改一个集合引起的,因此为什么我在唯一可能改变集合的行上添加了日志...

由于添加了日志记录,我们仍然遇到了问题,但是没有LOGGING出现:这并不奇怪,因为如果查看调用行上的参数(调用此Sub的唯一位置) - removemarks将作为False传递 - 这将通过递归调用一直向下传递,因此调用.Remove的行永远不会被执行....事实上我们没有看到日志记录证明了这一点....

任何人都可以看到可能导致此问题的任何其他内容!!!

全部谢谢

理查德

2 个答案:

答案 0 :(得分:1)

这是一种递归方法。这条线似乎导致了错误

If removemarks Then haystack.Remove(needlearray(i))

这里needlearray(i)可能会被内部递归方法修改,这将导致外部递归方法抛出此错误

答案 1 :(得分:1)

您正在迭代haystack.Values集合,然后递归回调,其中可能会调用此行:

If removemarks Then haystack.Remove(needlearray(i))

现在阅读代码,它应该有效,因为你的迭代器在haystack.Values,而不是haystack。但是我不知道Remove方法做了什么,也许它接触.Values

您有两种解决方法:

  • 使用for循环并在列表中向后计数,并按索引删除。
  • 收集要删除的内容列表,并在迭代器完成时执行它们。

我很确定LINQ附带了一个带有lambda的删除函数。