-1

环境:C#、VS2012、SharePoint 2010

我正在使用控制台应用程序与 SharePoint 网站进行交互,并且我正在尝试对一组警报标题进行简单的字符串比较...但是在调试时,有时会在特定的细绳。这是代码片段:

// This is pointing to a txt file with two lines in it, "folder1" and "folder3"
string[] aTitleList = System.IO.File.ReadAllLines(@"c:\path\to\specific\file.txt");
// Now we iterate through all the alerts to compare titles against those two lines
for (int i = oAlertCollection.Count - 1; i > -1; i--)
{
    System.Guid guid = oAlertCollection[i].ID;
    foreach (string sTitle in aTitleList)
    {
        if (oAlertCollection[i].Title.Contains(sTitle))
        {
            // At this point it throws the exception on the sTitle string
            // But ONLY on "folder3" and ONLY about half of the time
            // If I change it to something other than "folder3" it works 100%
        }
    }
}

这在其他人看来是不是很奇怪?我在这个应用程序中有很多其他方法可以进行类似的比较并且没有问题,即使使用“folder3”字符串,只有当我使用这个特定的数组时我才会遇到麻烦。

编辑 1 - 循环的深入解释:这种情况下的循环是删除与给定字符串匹配的项目。循环的设置方式,它从最后一个项目开始并迭代直到它达到 0(这是因为 SharePoint 自动将集合中每个项目的 ID 向下移动以替换已删除的项目,因此没有间隙,这也是它获取Count方法的地方,查看集合中编号最高的 ID)。澄清一下:该Count方法返回警报的总数,但实际的警报 ID 从 0 开始,因此for循环在使用i索引之前调整计数。如果该Count方法返回 0 个元素,则for循环将其设置为 -1 并且不会触发。

编辑 2 - 测试结果:我一直在对应用程序进行电池测试,虽然在使用阵列中的 2 个项目时我仍然无法找到它何时工作/炸弹之间的一致性,但我发现了一些可能会阐明原因的东西。如果我将数组增加到 3 个项目,它将始终失败。当第一个或第二个字符串比较为真并且项目被删除时,问题就出现了,因为此时foreach循环没有退出,它会继续针对现在不存在的警报测试剩余的字符串,这会引发异常。当数组中只有两个项目发生这种情况时,在第一个项目触发删除后测试第二个项目并不总是引发异常。一半的时间它“测试”已删除的警报,就好像它仍然在那里一样,并继续主循环。

作为参考,这是对SPAlertCollection工作原理的解释。即使在它被删除之后,它是否可能会在内存中短暂保留警报?这是我可以看到它每次测试已删除警报时都不会抛出异常的唯一方法。

最终编辑:问题得到了很好的回答,划线部分仍未得到解答,但最终与情况无关。

4

1 回答 1

2

As pointed out by Jim Mischel the following can only happen if you happen to delete elements from oAlertCollection in your loop


I'm going out on a limb and assume your oAlertCollection can sometimes hold 0 elements, which is why your code crashes on this line

if (oAlertCollection[i].Title.Contains(sTitle))

You'd then be trying to access position -1 in the array which throws an outofrange exception

You could avoid this by checking for oAlertCollection.Count's value before looping like this

if(oAlertCollection.Count() > 0)
{
    //for loop
}

This way if it actually holds 0 elements you avoid the error because it will not enter the loop

于 2013-03-04T22:35:03.760 回答