11
votes

Comment recréer "Index était en dehors des limites du tableau" Ajout d'articles au dictionnaire?

Je suis consistant à obtenir cette erreur sur une application multithreading .NET 3.5

Erreur 26 EXCEPTION SHROWARD. Détails: 'system.indexoutofRangeExceptionXception: l'index était en dehors des limites de la matrice.

à System.Collections.Generic.Dictionary`2.insert (Touche Twkey, Valeur TValue, Boolean Add)

à System.Collections.Generic.Dictionary`2.Ajouter (clé Thkey, valeur TValue)

Je pense que je sais comment le réparer (ajouter des serrures où appropriocier) mais j'aimerais pouvoir recréer ce problème sur mon environnement local, donc je serai sûr que je l'ai réparé et que je puisse aussi ajouter un test d'unité pour cela.

Connaissez-vous un moyen cohérent de recréer cela?


2 commentaires

Y a-t-il une raison particulière que vous n'utilisez pas concurrentdictionner ?


@Sconibulus: cette application est de 3,5, impossible d'utiliser ConcurrentDictionary :(


4 Réponses :


4
votes

Malheureusement, être cohérent dans une application multithreadée où se produisent des conditions de course n'est tout simplement pas réalisable.

Les différences matérielles seules entre votre machine et la production, on s'assurera que lorsqu'un problème se produise, il peut ne pas être au même endroit. Même si le matériel est identique, les différences logicielles (en particulier ces services de base) peuvent entraîner des différences de synchronisation et donc une situation où elle n'est tout simplement pas répétable.

Heck, si ces threads ont des dépendances sur des ressources externes (comme des appels de dB), les différences de latence de réseau entre la production et votre boîte de test pourraient vous assurer de ne jamais le dupliquer.

timide d'avoir un débogueur sur le serveur (mauvaise mauvaise idée), la meilleure chose à faire est une analyse visuelle du code, fixer les pièces que vous jugez nécessaires pour être corrigée, testez-la (aussi bien que vous le pouvez) puis relâchez et regardez-le en production.


0 commentaires

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

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

2 commentaires

Oui, cela oblige une erreur de dictionnaire, mais en fonction du reste du code de l'OP en jeu et de sa solution proposée, ce n'est pas vraiment utile.


Avec ce code, je suis perfectivement capable de recréer le problème, je ne peux malheureusement pas en dire la même chose avec mon code réel. Marquer la question telle que résolue depuis que je pense que c'est le meilleur que je puisse obtenir sans jeter des centaines de lignes de code au mélange. Merci!



1
votes

Cela ne vous aidera pas à recréer l'erreur localement, mais de supprimer complètement l'erreur, les documents MSDN pour le générique Dictionnaire dis:

Pour une alternative à thread-Safe, voir ConcurrentRentComment .

Les docs pour ConcurrentCugerary Dites: < / p>

représente une collection de filetage de paires de la valeur clé pouvant être accessible par plusieurs threads simultanément.

Note Cependant, ce concurrentdictionnaire est uniquement disponible en .NET 4 et UP.


1 commentaires

Mon application est 3.5, impossible d'utiliser ConcurrentDictionary :(



0
votes

Pourquoi ne créez-vous pas une enveloppe pour le dictionnaire avec une lecture de lecture. De cette façon, vous avez tous le verrouillage effectué dans une classe.


0 commentaires