Question

Nous avons découvert qu'un de nos assemblys généré automatiquement lève une exception StackOverflowException sur new (). Cette classe a (supportez-moi s'il vous plaît) plus de 400 propriétés simples qui sont initialisées (la plupart par défaut (chaîne) etc.) dans un constructeur.

Nous remarquons que son amende sur 64 bits, mais sur 32 bits, il va bang!

Nous devons vérifier s'il est raisonnable pour notre cas d'utilisation de créer une pile par défaut plus grande afin de nous donner une marge de manœuvre pendant la réingénierie du générateur de code.

Nous aimerions intéressé par les solutions qui impliquent app.config si possible. Mais je suis réaliste alors tout serait bien.

Raisons du débordement de pile. Nous avons limité l'erreur au constructeur en question. Mes premières impressions étaient aussi du type de la récursion infinie. Cependant, nous avons reproduit l'erreur à l'aide d'une application de console à 3 lignes:

  • crée une instance vide de la classe.
  • appelle une méthode non statique (Clone) sur la classe dont le premier travail consiste à créer une instance vide et prête à transmettre les propriétés.

Ça va cogner quand il frappe le deuxième constructeur.

maintenant en train de déboguer avec le code source .net, nous voyons que le débordement de pile est dans Guid.NewGuid () qui est passé en tant que deuxième paramètre au constructeur. La ligne de code actuelle est l'appel à l'appel natif de CoCreateGuid ().

Ainsi, bien qu'il puisse s'agir d'un bogue dans CoCreateGuid (), nous voulons éliminer notre code du problème. Ma première pensée est d’augmenter massivement la taille de la pile et de voir si cette erreur se reproduit. Ensuite, puisque je pense que nous pouvons contrôler tous les cas d’utilisation, il est nécessaire de remplacer le constructeur par une initialisation d’objet. Pensez que cela peut soulager la pile.

Nb. Nous pouvons empêcher l’erreur de se produire en supprimant uniquement la propriété int de la classe.

Était-ce utile?

La solution

Vous pouvez utilisez editbin pour modifier la taille de la pile de l'exécutable. Vous ne pouvez pas le faire dans app.config pour autant que je sache.

Une autre option (mentionnée également sur cette page) consiste à créer un nouveau fil avec le "droit". taille de la pile. La page mentionne les avantages et les inconvénients de cette approche.

Je serais surpris si le simple fait de définir 400 propriétés dans un constructeur a été à l'origine du problème, cependant ... cela va être un grand cadre de pile - mais à moins que vous n'ayez plusieurs grands cadres de pile sur la pile, je pense que tout ira bien. L’autre possibilité est que vous ayez une récursion sans fin quelque part:)

EDIT: une suggestion alternative ...

Vous avez probablement beaucoup de variables locales dans ce constructeur? (Sinon, il ne devrait pas prendre plus de pile que n'importe quel autre appel.) Est-il possible de scinder le constructeur en plusieurs méthodes, en définissant (par exemple) 20 champs par méthode? Ce sera délicat si les champs sont en lecture seule, certes.

Si vous pouviez nous donner une idée de ce à quoi ressemble le constructeur, cela aiderait beaucoup. Vous voudrez peut-être aussi utiliser ildasm pour voir quelle sera, selon lui, la taille de la pile pour ce constructeur.

Juste pour vérifier, c'est une classe plutôt qu'une structure, non?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top