-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に使用する前にカウントを調整します。メソッドが0要素を返すi場合、ループはそれを-1に設定し、起動しません。Countfor

編集2-テスト結果:私はアプリのバッテリーテストを行っていますが、アレイ内の2つのアイテムを使用しているときに、動作/爆弾の一貫性を見つけることができませんが、原因に光を当てる可能性のあるものを発見しました。配列を3項目に増やすと、一貫して失敗します。この問題は、最初または2番目の文字列の比較が真であり、アイテムが削除された場合に発生します。foreachループはその時点で終了しないため、現在存在しないアラートに対して残りの文字列のテストを続行し、例外をスローします。配列内の2つのアイテムのみでこれが発生した場合、最初のアイテムが削除をトリガーした後に2番目のアイテムをテストしても、常に例外がスローされるとは限りません。半分の時間、削除されたアラートがまだ存在するかのように「テスト」され、メインループを続行します。

参考までに、これはSPAlertCollectionがどのように機能するかについての説明です。アラートが削除された後でも、アラートが一時的にメモリに保持されている可能性がありますか?これが、削除されたアラートをテストするたびに例外がスローされないことを確認できる唯一の方法です。

最終編集:質問は十分に回答されています。打ち抜かれたセクションはまだ回答されていませんが、最終的には状況に関連していません。

4

1 に答える 1

2

Jim Mischelが指摘したようoAlertCollectionに、ループ内から要素を削除した場合にのみ、次のことが発生する可能性があります。


私は手足に出かけて、あなたoAlertCollectionが時々0個の要素を保持できると仮定します、それがあなたのコードがこの行でクラッシュする理由です

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

次に、配列内の位置-1にアクセスしようとすると、範囲外の例外がスローされます。

oAlertCollection.Countこのようにループする前にの値をチェックすることで、これを回避できます。

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

このように、実際に0個の要素を保持している場合は、ループに入らないため、エラーを回避できます。

于 2013-03-04T22:35:03.760 に答える