StackOverflowException sans récursivité ou boucle infinie?
Arrière-plan
J'ai un DataGridView
de contrôle qui je l'utilise, et j'ai ajouté mon gestionnaire ci-dessous pour les DataGridView.CellFormatting
événement pour que les valeurs de certaines cellules peut être rendu plus lisible par l'homme. Ce gestionnaire d'événement a été génial de travailler, la mise en forme de toutes les valeurs sans problème.
Cependant, récemment, j'ai découvert de très rares circonstances, les causes d'un bug rare. La colonne dans mon DataGridView
de l'élément date d'échéance a toujours un int
valeur. 0
indique que l'événement n'est jamais en raison, toute autre valeur est UTC timestamp de la date d'échéance. La db MySQL colonne correspondante n'autorise pas les valeurs null. Lorsque l'utilisateur a déplacé d'un DataGridView
ligne avec une date d'échéance, à un autre DataGridView
ligne avec une date d'échéance (à ce stade, tout est semble toujours très bien), puis appuie sur un bouton qui recharge les données de la base de données (sans envoi de mises à jour, essentiellement l'appel DataAdapter.Fill()
), le programme génère un StackOverflowException
**.
Pas de récursivité?
Ce qui est inhabituel pour moi, c'est que je ne vois pas où la récursivité ou infinie-la boucle est. J'ai ajouté int cellFormatCallCount
comme un membre de classe, et l'incrémenter lors de chaque appel, mais à l'époque, l'exception est levée, le débogueur affiche la valeur de ce int
comme 1, ce qui je l'espère parce que je n'ai pas l'impression et la récursivité a été de se produire.
Quelqu'un peut-il m'aider?
Comment puis-je voir une trace de la pile? Dans VS2008 il dit:
{Cannot evaluate expression because the current thread is in a stack overflow state.}
Cordialement,
Robinson
private int cellFormatCallCount = 0;
private void myDataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e) {
try {
//to format the cell, we will need to know its value and which column its in
string value = "";
string column = "";
//the event is sometimes called where the value property is null
if (e.Value != null) {
cellFormatCallCount++; //here is my test for recursion, this class member will increment each call
//This is the line that throws the StackOverflowException
/* ********************* */
value = e.Value.ToString();
/* ********************* */
column = actionsDataGridView.Columns[e.ColumnIndex].Name;
} else {
return; //null values cannont be formatted, so return
}
if (column == "id") {
//different code for formatting each column
} else if (column == "title") {
//...
} else {
//...
}
} finally {
cellFormatCallCount = 0; //after we are done with the formatting, reset our recursion counter
}
}
Je pensais que ce thread a propos de ce site web. Garçon, j'ai besoin d'une pause =p
Moi aussi! J'ai été à essayer de comprendre comment il a obtenu une exception à partir du site web. Sheesh!
Si vous mettez un point d'arrêt sur la ligne incriminée, pouvez-vous étape dans l'accès à la propriété de l'e.De la valeur? Pouvez-vous aperçu rapide de l'e.De la valeur? Si oui, que voyez-vous?
C'est un long shot, mais qu'est-ce que l'e.De la valeur? Si le ToString qui est définie de manière récursive, alors vous pourriez avoir un stackoverflow. Oui ça peut paraître fou, mais plus facile que vous pourriez penser, surtout quand vous avez un objet avec une propriété qui permet de faire un "jeu" avec le type d'Objet qui peut se contenir lui-même.
OriginalL'auteur gnirts | 2009-04-22
Vous devez vous connecter pour publier un commentaire.
Apparemment e.De la valeur.ToString() appelle la CellFormatting événement. Cela semble assez logique. Il devrait être assez facile à trouver avec un débogueur.
Mais la récursivité peut être causé quelque part d'autre, comme dans la colonne de mise en forme que vous avez omis.
Votre vérifier la récursivité n'est pas fiable, étant donné que la Valeur==null également réinitialiser, et il semble être partagée par toutes les colonnes. Faire entourer l'e.De la valeur.ToString() plus étroitement:
OriginalL'auteur Henk Holterman
Totalement estimation aléatoire (pas de trace de la pile, c'est tout ce que je peux faire)...
Êtes-vous tenter pour affichage/format d'un type qui a un potentiel récursive
ToString()
?Une faute de frappe/d'erreur comme susceptible de provoquer un
StackOverflowException
...si vous souhaitez voir le débordement de la pile, vous devez placer un point de rupture où ça se passe, plutôt que l'exception. je voudrais essayer de le mettre sur la ligne où il est dit, en est AINSI, et en essayant de voir où cela va.
Non, je n'ai pas sous-classe DataGridViewCellFormattingEventArgs.
Si vous définissez un (éventuellement sous conditions) point d'arrêt sur la ligne qui est à l'origine de la SORTE, vous devriez être en mesure de l'étape en elle ... qui peuvent vous aider à identifier les récursive chemin...
Eh bien, vous pouvez tester un négatif sur la méthode ToString() en plaçant un équivalent électronique.De la valeur.ToString() plus tôt dans la méthode et voir si vous obtenez le stackoverflow... Si vous n'avez pas il ne peut pas être le ToString. Je jut pense qu'il serait étrange si l' .filet, à condition DataGridViewCellFormattingEventArgs classe en œuvre ToString de cette façon 🙂
OriginalL'auteur Daniel LeCheminant
Étant donné que c'est un événement, pourrait-il être le déclenchement de son auto?
Mais vous n'êtes pas le forcer à le repeindre à partir de l'intérieur de la méthode som eof pas montré de code? Autre chose, avez-vous essayé avec le try/finally bloc, juste au cas où c'est un réglage à 0 sans que vous en ayez connaissance.
OriginalL'auteur BCS
Essayer de faire le cellFormatCallCount variable statique de sorte qu'il partagé par toutes les instances de la classe. Je soupçonne qu'en quelque sorte, l'événement est le déclenchement de lui-même, mais que vous ne voyez pas parce que cellFormatCallCount n'est locale à chaque instance de la classe qui gère l'événement et donc n'est jamais incrémenté au-delà de 1. Si c'est le cas, alors le véritable déclencheur de la stackoverflow (récursivité) pourrait être n'importe où dans la méthode et il se trouve à court d'espace de pile à cette ligne.
Une fois que vous avez pris la variable statique, vous pouvez jeter une exception lorsqu'il dépasse une certaine (petite) valeur de 2. Cette exception doit laisser visible la trace de pile autour de.
OriginalL'auteur tvanfosson
@Daniel: Si c'était la question, ne serait-ce pas déjà lever l'exception de la ligne:
@gnirts: Pourriez-vous poster la méthode complète et la trace de la pile trop?
@BCS (ci-dessous): je pense que peut-être elle, mais il pourrait facilement être une partie du code qui n'est pas montré dans le deo posté.
PS. Je suis désolé, c'était un commentaire, mais je n'ai pas assez de répétitions 😀
Oh que c'est gentil! Merci 😀
Et vous avez été correct à 100% que le plus tôt serait soulevé l'exception ;]
OriginalL'auteur asgerhallas
Il n'a aucun rapport avec le problème, mais vous pouvez en fait avoir un
StackOverflowException
sans récursivité à tout juste avec:cela permettrait d'avoir une trace de la pile. un véritable débordement de pile ne permet pas d'évaluer quoi que ce soit.
Kopp: Un "vrai" StackOverflow vous donne la possibilité de demander, répondre et commenter des questions 🙂
OriginalL'auteur
J'Ai juste eu un problème similaire de stackoverflow, sans aucune trace de détails.
Mon problème était dû à une instance d'un objet qui ne devrait pas avoir été instancié. J'ai enlevé la délinquance nouvel objet et tout était bien.
Dans les circonstances ci-dessus sans voir plus de code, de s'assurer de multiples événements ne sont pas activés à l'aide de l' =- pour annuler les événements en conséquence.
J'espère que cela peut aider quelqu'un.
OriginalL'auteur peterincumbria