Pourquoi mon application IIS7 pool shutdown après une exception dans une DLL appelée d'un ASP.NET page?

j'ai lu les messages ASP.NET problème d'arrêt de la piscine d'application et IIS 7.5: problème avec la piscine d'Application mais ils n'ont pas répondu à ma question.

j'ai un C# ASP.NET page qui en code-derrière instancie une classe d'une DLL fournie via le répertoire BIN, puis appelle une méthode sur cette instance. La méthode à l'intérieur de la DLL lance System.ArgumentException en raison d'une colonne non existante dans un DataRow objet. Le journal des événements affiche l'erreur suivante:

Source: ASP.NET 2.0.50727.0
Application ID: /LM/W3SVC/1/ROOT/...
Process ID: 9476
Exception: System.ArgumentException
Message: Column 'someColumn' does not belong to table.
StrackTrace: 

le code d'appel dans le ASP.NET page enveloppant l'appel de méthode dans un bloc Générique try-catch . Lorsque je demande la page, cela bloque le pool d'applications correspondant de mon instance IIS et mon site web n'est plus disponible (erreur 503). Je dois manuellement redémarrer le pool d'applications et le site fonctionne à nouveau.

mise à Jour Comme demandé le bloc try catch de les ASP.NET code derrière:

try
{
    SomeExternalClass someExternalClass = new SomeExternalClass();
    someExternalClass.SomeMethod( someId );
}
catch( Exception ex )
{
    // "smp" is an instance of "StatusMessagePanel", a control we use on all pages 
    // to show error information, basically a div container with an icon.
    smp.ShowError( ex.Message ); 
}

maintenant ma question est pourquoi une exception relativement "simple" comme le System.ArgumentException étant jeté en essayant d'accéder à une non existante DataRow colonne, écrase tout le site web? Le bloc Générique try-catch de la ASP.NET page help, ce ne devrait pas être la raison pour rendre complètement l'ensemble du site web indisponible, ou est-ce une hypothèse erronée? Je n'aurais jamais pensé que cela puisse prendre le serveur (II) vers le bas.

en prévision des gens me disant que je devrais vérifier l'existence des colonnes avant d'y accéder: je sais à ce sujet et le code d'héritage a maintenant été changé, mais ce n'est pas ma question comme décrit ci-dessus, je voudrais savoir pourquoi les conséquences sont si drastiques.

Update 2

la méthode en question étant appelée à l'intérieur de la DLL démarre un fil qui est enveloppé dans un try-catch bloc:

[...]
try
{
    ThreadStart starter = () => CreateReport(...)
    Thread thread = new Thread( starter );
    thread.Start();
    if( !thread.Join( TimeSpan.FromMinutes( 15 ) ) )
    {
        // Log some timeout warning
    }
    else
    {
        // Log information about successful report generation
    }
}
catch( Exception ex )
{
    // Log error information
}
21
demandé sur Community 2013-04-12 19:25:12

2 réponses

il est fort probable que votre pool d'applications soit arrêté automatiquement par la fonction Rapid Fail Protection de IIS , comme vous le constatez dans les questions liées. Si vous vérifiez votre journal d'événements, il peut y avoir de multiples exceptions non manipulées étant jetées dans la succession rapide.

simplement mis, assez d'exceptions non gérées dans un intervalle de temps configurable (la valeur par défaut est de 5 en 5 minutes) va fermer L'AppPool, provoquant la réponse indisponible du Service 503.

le raisonnement derrière cette fonctionnalité est que si vous avez une application défectueuse, vous ne voulez probablement pas qu'elle soit automatiquement redémarrée à chaque demande ultérieure, consommant des ressources et peut-être corrompant des données.

je dois admettre que ce n'est pas le comportement" par défaut " auquel je m'attendais non plus.

Check out Rick Stahls explication , c'est un peu plus en profondeur.

à vraiment résoudre ce problème, vous devez attraper l'exception, ou d'empêcher l'exception d'être jeté (comme @leppie l'indique). Les exceptions non gérées sont censées détruire l'ensemble du processus d'exécution (ce qui signifie qu'une seule requête/processus du worker, pas IIS) - cela rend le code .Net beaucoup plus facile à déboguer, parce qu'il ne cache pas les erreurs ou simplement accrocher l'application.

notez que ceci a été changé dans .Net 2.0:

http://msdn.microsoft.com/en-us/library/ms228965.aspx

http://support.microsoft.com/kb/911816

mise à Jour

Sur la base de votre mise à jour ci-dessus, je ne pense pas que votre exception soit réellement prise, si elle est lancée de CreateReport() . Cette méthode s'exécute sur un thread séparé:

exception still thrown

You besoin d'un try-catch dans le corps de CreateReport() s'il n'y en a pas déjà un:

public static void CreateReport() {
    try {
        throw new Exception("reducto");
    } catch {
        Console.WriteLine("done did.");
    }
}
19
répondu Zachary Yates 2013-04-25 04:43:24

ça m'est arrivé une fois. La véritable erreur (dans mon cas) était un débordement de pile qui fermait la piscine.

il semble que IIS se protégeait de consommer trop de ressources.

j'ai trouvé le problème en utilisant DebugDiag.

C'est ici que j'ai commencé: http://www.webdebug.net/index.php/2012/12/collect-iis-crash-dump-with-debugdiag /

comme pour comprendre pourquoi une exception dans une DLL externe peut causer la piscine d'application IIS à l'arrêt, même si l'exception est prise à l'intérieur de la DLL et aussi en appelant la méthode de DLL de l'intérieur du code derrière le ASP.NET page.

la dll externe s'exécute également dans votre pool d'applications. Un crash majeur dans cette dll causera aussi un crash dans votre pool d'applications. Certaines exceptions ne peuvent pas être maniées et l'exception stackoverflow en est une. L'objet est discutée ici . C'est peut-être ce qui s'est passé dans votre cas.

4
répondu Guish 2013-04-23 21:26:11