12

マルチスレッドの.net 3.5アプリケーションで一貫してこのエラーが発生しています

ERROR 26 例外がスローされました。詳細: 'System.IndexOutOfRangeException: インデックスが配列の範囲外でした。

System.Collections.Generic.Dictionary`2.Insert (TKey キー、TValue 値、ブール値の追加) で

System.Collections.Generic.Dictionary`2.Add (TKey キー、TValue 値) で

私はそれを修正する方法を知っていると思います(適切な場所にロックを追加します)が、ローカル環境でこの問題を再現できるようにしたいので、修正したことを確認し、単体テストを追加できるようにしますそれのための。

これを再現する一貫した方法を知っていますか?

4

4 に答える 4

9
Dictionary<string, string> dict = new Dictionary<string, string>();

Task.Factory.StartNew(() => { while (true) dict["a"] = "a"; });
Task.Factory.StartNew(() => { while (true) dict.Remove("a"); });
于 2012-10-05T14:24:51.907 に答える
4

残念ながら、競合状態が発生するマルチスレッド アプリケーションで一貫性を維持することは、まったく不可能です。

お使いのマシンと実稼働マシンのハードウェアの違いだけでも、問題が発生したときに同じ場所にない可能性があります。ハードウェアが同じであっても、ソフトウェアの違い (特にバックグラウンド サービス) によってタイミングの違いが生じる可能性があり、その結果、再現できない状況が発生する可能性があります。

それらのスレッドが外部リソース (DB 呼び出しなど) に依存している場合、本番環境とテスト ボックスの間のネットワーク レイテンシの違いにより、それを複製することはできません。

サーバー上にデバッガーを配置するのは気が進まないので (まずい考えです)、できる最善の方法は、コードを視覚的に分析し、修正が必要だと思われる部分を修正し、(可能な限り) テストしてからリリースすることです。制作中にご覧ください。

于 2012-10-05T14:22:16.773 に答える
1

これはローカルでエラーを再現するのに役立ちませんが、エラーを完全に取り除くために、一般的な辞書<TKey、TValue>のmsdnドキュメントは次のように述べています。

スレッドセーフな代替手段については、ConcurrentDictionary <TKey、TValue>を参照してください。

ConcurrentDictionary <TKey、TValue>のドキュメントには次のように書かれています。

複数のスレッドから同時にアクセスできるキーと値のペアのスレッドセーフなコレクションを表します。

ただし、ConcurrentDictionary <TKey、TValue>は.Net4以降でのみ使用可能であることに注意してください。

于 2012-10-05T14:27:14.760 に答える
0

ReaderWriterLockSlim を含む Dictionary のラッパーを作成してみませんか。そうすれば、すべてのロックを 1 つのクラスで行うことができます。

于 2012-10-05T14:38:05.097 に答える