10
votes

Les causes alternatives de l'index étaient en dehors des limites du tableau dans le dictionnaire .NET

Je comprends que l'une des principales causes de l'index en dehors de l'erreur limites d'un objet dictionnaire est une collision de fil. (Lecture et écriture dans le même dictionnaire en même temps) Cependant, je suis tombé sur un cas perplexe où la collision du fil n'est pas une explication suffisante.

Voici la situation: J'ai écrit du code qui implémente le dictionnaire de manière dangereuse pour un traitement multi-fileté.

Le code a été implémenté en tant que service Web sur deux serveurs, serveur A et B. Les clés sont accessibles via un équilibreur de charge qui enverra des demandes au serveur A et B de la manière de Round Robin.

Maintenant voici la partie délicate. L'erreur apparaît uniquement sur le serveur A et ne jamais sur serveur B. Selon notre équipe matérielle, les deux serveurs sont identiques. Bien que la collision du fil soit intrinsèquement un processus aléatoire, il devrait toujours affecter à la fois mes serveurs de manière égale. Je vois 50+ instances de l'erreur sur un serveur et 0 sur un autre. Il est statistiquement improbable que les collisions de thread ne se produisent que sur l'un de mes serveurs tandis que l'autre fonctionne sans erreur.

Je modifie déjà l'application pour le faire filer plus sûre, mais quelles autres raisons peuvent exister pour cette erreur pour que cette erreur soit lancée lors de l'insertion d'un objet dictionnaire?


5 commentaires

Êtes-vous sûr que l'équilibreur de charge envoie des demandes au serveur B? Peut-être que cela n'affecte que le premier serveur.


Peut-être qu'un serveur a un système d'exploitation 32 bits et l'autre un 64 bits?


@ petro.sidlovskyy J'ai confirmé que les deux serveurs ont une circulation basée sur des fichiers journaux.


Pouvez-vous effectuer une mise à niveau vers .NET 4 et utilisez un concurrentdictionner ?


@Gabe Mise à niveau vers .NET 4 n'est pas possible


3 Réponses :


1
votes

Ceci est probablement extrêmement extrait, mais vous savez-vous si vos connexions aux deux serveurs via l'équilibreur de charge sont égaux? (Je ne sais pas vraiment quoi que ce soit sur la façon dont les œuvres d'équilibrage de la charge, cela pourrait donc être une pensée stupide de la gove.)

Je pense que je pense que vous avez un peu plus de latence de réseau dans votre connexion au serveur B que de serveur A. Cela pourrait fournir une distance suffisante entre les demandes de client sur ce serveur, ce qui permet d'obtenir des accès au dictionnaire, vous permettant de vous lâcher avec votre multithread code qui ne parle pas stricement en sécurité.

Si demande d'atteindre un serveur un peu plus rapide, cela pourrait faire la différence qui vous donne les erreurs hors de portée.

Comme je l'ai dit, probablement lointain-extrait - juste une idée. Je pensais que cela ne pouvait pas faire mal de le jeter là-bas.


0 commentaires

0
votes

Je ne peux pas expliquer pourquoi cela ne fonctionne pas chez un serveur mais pas l'autre. Toutefois, vos problèmes sont des problèmes multithreading.

Comme vous l'avez peut-être remarqué, cela ne fonctionnera pas dans un environnement multithread: xxx

même chose pour: < PRE> XXX

Qu'est-ce qui pourrait vous surprendre, c'est que TrygetValue n'est pas en sécurité: xxx

référence: http://www.grumpyDev.com/2010/02/25/Trthead-Safe-DictionaryTeytvalue/


1 commentaires

Cela ne devrait-il pas vraiment vous surprendre car ils ne sont pas threads des collections en sécurité dans le premier cas?



7
votes

Bien que la collision de thread est intrinsèquement un processus aléatoire

Pas du tout. Il dépend de manière critique du timing. Et la timing peut être répétable, les systèmes ont tendance à s'installer dans des modèles spécifiques. Un outil de diagnostic de course de fil de thread, tels que les échecs de Microsoft Recherche Works en injectant des retards aléatoires dans une exécution d'un fil. Pour que le système tombe à l'extérieur d'un tel motif. Comme il fait de temps en temps seul, mais seulement une fois par semaine environ. que est aléatoire, tout simplement pas suffisamment aléatoire pour vous donner un tir un coup de débogage du problème.

Ainsi, voir un échec du serveur et non l'autre ne veut rien dire. L'équilibreur de charge a probablement quelque chose à voir avec cela. Vous ne serez jamais capable de comprendre la raison exacte car vous ne pouvez pas découvrir ce qui s'est passé ces 50 fois. Ça ne suffit pas.


0 commentaires