最近、一般的な辞書を使用しているときに次の例外が発生していました
InvalidOperationException が発生しました。コレクションが変更されました
このエラーの主な原因は、使用していた静的辞書のスレッド セーフの問題であることがわかりました。
ちょっとした背景: 私は現在、この問題に関連する 3 つの異なるメソッドを持つアプリケーションを持っています。
- メソッド A は、値を使用してディクショナリを反復処理し
foreach
、値を返します。 - メソッド B はデータをディクショナリに追加します。
- メソッド C は、ディクショナリ内のキーの値を変更します。
ディクショナリを繰り返し処理しているときに、データも追加されることがあり、これがこの問題の原因です。foreach
辞書の内容を繰り返し処理するコードの部分で、この例外が発生し続けます。この問題を解決するために、ジェネリック ディクショナリを に置き換えました。実行ConcurrentDictionary
した内容の詳細は次のとおりです。
目的:私の主な目的は、例外を完全に削除することです
メソッドB(辞書に新しいキーを追加する)の場合、次のように置き換え.Add
ましたTryAdd
メソッド C (辞書の値を更新する) については、何も変更しませんでした。コードの大まかなスケッチは次のとおりです。
static public int ChangeContent(int para)
{
foreach (KeyValuePair<string, CustObject> pair in static_container)
{
if (pair.Value.propA != para ) //Pending cancel
{
pair.Value.data_id = prim_id; //I am updating the content
return 0;
}
}
return -2;
}
メソッド A の場合- ディクショナリを反復処理しているだけで、ここで実行中のコードが (デバッグ モードで) 停止し、Visual Studio からエラーが発生した場所であることが通知されます。使用しているコードは次のようなものです。
static public CustObject RetrieveOrderDetails(int para)
{
foreach (KeyValuePair<string, CustObject> pair in static_container)
{
if (pair.Value.cust_id.Equals(symbol))
{
if (pair.Value.OrderStatus != para)
{
return pair.Value; //Found
}
}
}
return null; //Not found
}
これらの変更により、発生している例外が解決されますか?
編集:
このページでは、このメソッドを使用すると、書き込みと並行して要素をトラバースできると述べてGetEnumerator
います (ただし、時代遅れかもしれません)。foreach を使用するのと同じではありませんか?