Question

Environment: C#, VS2012, SharePoint 2010

I'm using a console application to interface with a SharePoint site and I'm trying to do a simple string comparison against a collection of alert titles... but when debugging I am getting an "out of range" exception sometimes on a specific string. Here's the code snippet:

// 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%
        }
    }
}

Does that seem bizarre to anyone else? I have tons of other methods in this application that do similar comparisons and have no problems, even when using the "folder3" string, it's only when I use this specific array that I run into trouble.

Edit 1 - In-depth explanation of loop: The loop in this case is deleting the items that match the given strings. The way the loop is set up, it starts with the last item and iterates until it reaches 0 (this is because SharePoint automatically shifts the ID of each item in a collection down to replace the one that was deleted so there are no gaps, this is also where it gets the Count method, looking at the highest numbered ID in the collection). To clarify: The Count method returns the total number of alerts, but the actual alert IDs start at 0, so the for loop adjusts the count before using i to index them. If the Count method returns 0 elements, the for loop sets that to -1 and does not fire.

Edit 2 - Test results: I have been battery testing the app and while I still cannot find a consistency between when it works/bombs while using 2 items in the array, I discovered something that may shed some light on the cause. If I increase the array to 3 items, it will fail consistently. The problem comes when the first or second string comparison is true and the item is deleted, because the foreach loop does not exit at that point, it continues to test the remaining strings against the now non-existent alert, which throws the exception. When this happens with only two items in the array, testing the second item after the first one triggered the delete does not always throw an exception. Half of the time it "tests" the deleted alert as if it were still there and continues with the main loop.

For reference, this is the explanation of how SPAlertCollection works. Could it perhaps be holding the alert in memory briefly even after it's deleted? That's the only way I could see it NOT throwing an exception every time it tests the deleted alert.

Final Edit: The questions is answered well enough, the struck-through section is still unanswered but ultimately not relevant to the situation.

Was it helpful?

Solution

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top