2010-10-06 4 views
4

Si j'ai une méthode que je sais potentiellement récursif infiniment, mais je ne peux pas prédire avec certitude quelles conditions/paramètres provoqueraient, quel est un bon moyen en C# de le faire:Quelle est une bonne façon générale d'intercepter une exception StackOverflow en C#?

try 
{ 
    PotentiallyInfiniteRecursiveMethod(); 
} 
catch (StackOverflowException) 
{ 
    // Handle gracefully. 
} 

Il est évident que dans la thread principal vous ne pouvez pas faire cela, mais on m'a dit à quelques reprises qu'il est possible de le faire en utilisant des threads ou AppDomain, mais je n'ai jamais vu un exemple de travail. Quelqu'un sait-il comment cela se fait de manière fiable?

+0

Pouvez-vous redessiner votre algorithme? –

+0

Ce n'est pas forcément mon algorithme; par exemple, la méthode 'Transform' sur un objet' XslCompiledTransform' va se casser si XSLT a un modèle récursif dedans. – Flynn1179

+0

Pouvez-vous réparer le XSLT? – Arcturus

Répondre

11

Vous ne pouvez pas. De MSDN

A partir du .NET Framework version 2.0 , un objet StackOverflowException ne peut pas être interceptée par un bloc try-catch et le processus correspondant est terminé par défaut. Par conséquent, les utilisateurs sont invités à écrire leur code pour détecter et empêcher une pile débordement. Par exemple, si votre application dépend de la récursivité, utilisez un compteur ou une condition d'état à pour terminer la boucle récursive. Notez qu'une application qui héberge le Common Language Runtime (CLR) peut spécifier que le CLR déchargent le domaine d'application où la pile exception de débordement se produit et laisser le processus correspondant continuer. Pour plus d'informations, voir ICLRPolicyManager Interface et Présentation de l'hébergement.

+0

En fait, à partir de cet extrait, je suppose que vous pouvez; il indique spécifiquement qu'un processus continuera si le domaine d'application où l'exception s'est produite est déchargé. Cela implique qu'il est possible d'exécuter la méthode dans son propre domaine d'application; Ma question est la suivante: comment cela peut-il être fait? – Flynn1179

+0

Ce lien peut s'avérer utile: http://msdn.microsoft.com/fr-fr/library/dd380850.aspx. Il a décrit comment charger de nouveaux domaines d'application. Peut-être que cela pourrait être l'idée la plus gracieuse. Mais l'hébergement d'un nouveau AppDomain semble un peu exagéré. Pouvez-vous valider le XSLT pour les références circulaires? – Arcturus

+0

Ce n'est pas trivial à faire, mais ce n'est pas le point; Je suis à la recherche d'une solution générale, indépendamment de ce qui provoque le débordement de la pile. – Flynn1179

1

Il n'y a pas moyen d'attraper StackOverflowException, mais vous pouvez faire quelque chose à l'exception non gérée:

static void Main() 
{ 
AppDomain.CurrentDomain.UnhandledException += 
    new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 
} 

static void CurrentDomain_UnhandledException 
    (object sender, UnhandledExceptionEventArgs e) 
{ 
    try 
    { 
    Exception ex = (Exception)e.ExceptionObject; 

    MessageBox.Show("Whoops! Please contact the developers with the following" 
      + " information:\n\n" + ex.Message + ex.StackTrace, 
      "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop); 
    } 
    finally 
    { 
    Application.Exit(); 
    } 
} 
+0

Cela ne se déclenchera pas sur une exception StackOverflow, j'ai essayé, du moins pas depuis AppDomain.CurrentDomain. – Flynn1179

Questions connexes