2012-10-05 11 views
9

mam consistenlty otrzymuję ten błąd w aplikacji .NET wielowątkowość 3,5Jak odtworzyć "Indeks znajdował się poza granicami tablicy", dodając elementy do słownika?

ERROR 26 Wyjątek rzucony. Szczegóły: 'System.IndexOutOfRangeException: Indeks był poza granicami tablicy.

na System.Collections.Generic.Dictionary`2.Insert (klucz, wartość TValue TKey, Boolean) Dodaj

w System.Collections.Generic.Dictionary`2.Add (klucz TKey, wartość TValue)

Myślę, że wiem, jak to naprawić (dodając blokady, które są odpowiednie), ale chciałbym móc odtworzyć ten problem w moim lokalnym środowisku, więc będę pewien, że to naprawiłem, a także będę w stanie aby dodać test jednostkowy dla niego.

Czy znasz jakiś spójny sposób na odtworzenie tego?

+0

Czy istnieje szczególny powód, dla którego nie używasz 'ConcurrentDictionary'? – Sconibulus

+0

@Sconibulus: ta aplikacja ma 3.5, nie można używać 'ConcurrentDictionary' :( – StackOverflower

Odpowiedz

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

Task.Factory.StartNew(() => { while (true) dict["a"] = "a"; }); 
Task.Factory.StartNew(() => { while (true) dict.Remove("a"); }); 
+0

Tak, to wymusza błąd słownika, ale w zależności od reszty kodu OP, który jest w grze ORAZ jego proponowanego rozwiązania, to nie jest dokładnie pomocny: – NotMe

+0

Dzięki temu kodowi jestem perfekcyjnie zdolny do odtworzenia problemu, niestety nie mogę powiedzieć tego samego z moim prawdziwym kodem. Oznaczenie pytania jako rozwiązane, ponieważ uważam, że jest to najlepsze, co mogę osiągnąć bez rzucania setek linii kodu do miksu. Dzięki! – StackOverflower

4

Niestety, bycie konsekwentnym w wielowątkowej aplikacji, w której występują warunki rasowe, jest po prostu nieosiągalne.

Różnice sprzętowe występujące między urządzeniem a urządzeniem produkcyjnym zapewniają, że w przypadku wystąpienia problemu może nie być w tym samym miejscu. Nawet jeśli sprzęt jest taki sam, różnice w oprogramowaniu (szczególnie te usługi tła) mogą prowadzić do różnic czasowych, a zatem sytuacji, w których nie jest to powtarzalne.

Heck, jeśli te wątki mają zależności od zasobów zewnętrznych (np. Wywołania DB), różnice w opóźnieniach sieci między produkcją a polem testowym mogą zapewnić, że nigdy nie będzie można go powielić.

Nieśmiały z debuggera na serwerze (zły, zły pomysł), najlepszą rzeczą jaką możesz zrobić, to wizualna analiza kodu, naprawienie części, które uważasz za konieczne do naprawienia, przetestuj (tak jak możesz) następnie zwolnij i obejrzyj go w produkcji.

+0

+1 dzięki za odpowiedź – StackOverflower

1

to nie pomoże odtworzyć błąd lokalnie, ale w celu usunięcia błędu całkowicie docs MSDN generycznego Dictionary<TKey, TValue> powiedzieć:

Dla wątku bezpieczny alternatywa, patrz ConcurrentDictionary<TKey, TValue> .

Docs dla ConcurrentDictionary<TKey, TValue> powiedzieć:

Reprezentuje wątek bezpieczny zbiór par klucz-wartość, którą można dostępne dla wielu wątków jednocześnie.

Uwaga jednak, że ConcurrentDictionary < TKey, TValue > jest dostępna tylko w .NET 4 i do góry.

+0

moja aplikacja ma 3,5, nie można używać 'ConcurrentDictionary' :( – StackOverflower

0

Dlaczego nie stworzysz wrappera dla Słownika z Czytnikiem ReaderRockLockSlim. W ten sposób wszystkie blokady zostaną wykonane w jednej klasie.

Powiązane problemy