2013-04-12 10 views
21

Ich habe die Beiträge ASP.NET application pool shutdown problem und IIS 7.5: problem with Application pool gelesen, aber sie haben meine Frage nicht beantwortet.Warum wird mein IIS7-Anwendungspool nach einer Ausnahme in einer von einer ASP.NET-Seite aufgerufenen DLL heruntergefahren?

Ich habe eine C# ASP.NET-Seite, die in Code-Behind eine Klasse aus einer DLL über das BIN-Verzeichnis instanziiert, dann ruft eine Methode für diese Instanz. Die Methode innerhalb der DLL löst System.ArgumentException aufgrund einer nicht vorhandenen Spalte in einem DataRow Objekt aus. Das Ereignisprotokoll zeigt die folgende Fehlermeldung:

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: 

Der Aufrufcode in der ASP.NET-Seite wickelt den Methodenaufruf in einem allgemeinen try-catch Block. Wenn ich die Seite anfordere, stürzt dies den entsprechenden Anwendungspool meiner IIS-Instanz ab und meine Website ist nicht mehr verfügbar (Fehler 503). Ich muss den Anwendungspool manuell neu starten und die Site funktioniert wieder.

aktualisieren Wie forderte, den try catch Block vom ASP.NET-Code hinter:

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); 
} 

Jetzt ist meine Frage, warum eine relativ „einfache“ Ausnahme wie die System.ArgumentException geworfen wird, wenn versucht, ein für den Zugriff auf nicht vorhandene DataRow Spalte, stürzt die gesamte Website? Auch der generische Block try-catch der ASP.NET-Seite hilft nicht, noch sollte dies der Grund sein, die gesamte Website komplett zu sperren, oder ist das eine falsche Annahme? Ich hätte nie gedacht, dass dies den (II) Server im Grunde nehmen kann.

In Erwartung der Leute, die mir sagen, dass ich auf Säulenexistenz prüfen sollte, bevor ich auf sie zugreife: Ich weiß darüber, und der Legacy-Code wurde jetzt geändert, aber das ist nicht meine Frage, wie oben beschrieben zu wissen, warum die Folgen so drastisch sind.

Update 2

Verfahren in Frage innerhalb der DLL aufgerufen wird startet einen Thread, der in einem try-catch Block gewickelt wird:

[...] 
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 
} 
+0

Was im catch-Block passiert? Wenn das eine Ausnahme auslöst, könnten Sie in Schwierigkeiten geraten. Kannst du den Try Catch Code posten? – levelnis

+0

Der catch-Block ruft eine Methode auf, die die Fehlermeldung nur für den Client (Browser) sichtbar macht, ich werde meine Frage aktualisieren. – Gorgsenegger

+0

Nur um mir Spaß zu machen - wenn Sie den try-catch-Block vollständig entfernen und nur die Methode aufrufen, stürzt der App-Pool noch ab? – levelnis

Antwort

19

Höchstwahrscheinlich wird Ihr Anwendungspool automatisch von der Funktion IIS's Rapid Fail Protection heruntergefahren, wie Sie in den verknüpften Fragen notieren. Wenn Sie Ihr Ereignisprotokoll überprüfen, können mehrere nicht behandelte Ausnahmen in schneller Folge ausgelöst werden.

Einfach ausgedrückt, genug nicht behandelte Ausnahmen in einer konfigurierbaren Zeitspanne (der Standardwert ist 5 in 5 Minuten) wird den AppPool herunterfahren, was die Antwort 503 Service nicht verfügbar verursacht.

Der Grund für diese Funktion ist, dass Sie bei einer fehlerhaften Anwendung wahrscheinlich nicht möchten, dass sie bei jeder nachfolgenden Anforderung automatisch neu gestartet wird, Ressourcen verbraucht und möglicherweise Daten beschädigt.

Ich muss zugeben, dass dies nicht das "Standard" Verhalten ist, das ich auch erwartet hätte.

Check out Rick Stahls explanation, es ist ein bisschen mehr in die Tiefe.

Um dies wirklich zu beheben, müssen Sie die Ausnahme abfangen oder verhindern, dass die Ausnahme ausgelöst wird (wie von @leppie vorgeschlagen). Unbehandelte Exceptions sollen den gesamten Ausführungsprozess abreißen (was bedeutet, dass ein einzelner Request/Worker-Prozess, nicht IIS) - .Net-Code viel einfacher zu debuggen macht, weil es die Fehler nicht versteckt oder einfach die Anwendung aufhängt.

Beachten Sie, dass diese in .NET 2.0 geändert wurde:
http://msdn.microsoft.com/en-us/library/ms228965.aspx
http://support.microsoft.com/kb/911816

aktualisieren
oben auf Ihrem Update Basierend, ich glaube nicht, Ihre Ausnahme tatsächlich gefangen wird, wenn er ausgelöst wird, von CreateReport(). Diese Methode wird auf einem separaten Thread ausführen:

exception still thrown

Sie benötigen eine Try-Catch im Körper CreateReport(), wenn es nicht einen bereits:

public static void CreateReport() { 
    try { 
     throw new Exception("reducto"); 
    } catch { 
     Console.WriteLine("done did."); 
    } 
} 
+0

Danke für die detailliertere Information, obwohl ich immer noch nicht verstehe, warum eine Ausnahme *, die innerhalb der DLL * gefangen wird, dazu führen kann, dass der Anwendungspool heruntergefahren wird. Mehrere Ausnahmen, die in schneller Folge ausgelöst werden, sollten ebenfalls nicht der Fall sein, da die Ausführung der DLL-Methode mit der ersten Ausnahme beendet wird, die ausgelöst wird. Das Ereignisprotokoll zeigt außerdem, dass nur eine Ausnahme generiert wurde. – Gorgsenegger

+0

@Gorgsenegger hat die Antwort basierend auf Ihrem Feedback aktualisiert –

+0

Vielen Dank, ich werde versuchen, dies zu überprüfen, sobald ich die Zeit gefunden habe - wir haben unser TFS in ein anderes Netzwerk verlegt und sind immer noch dabei, es wieder auf den neuesten Stand zu bringen Entschuldigen Sie die Verspätung und bitte tragen Sie ein paar Tage mit mir. – Gorgsenegger

4

es mir passiert ist einmal. Der eigentliche Fehler (in meinem Fall) war ein Stack-Overflow, der den Pool heruntergefahren hat.

Es sieht so aus, als ob IIS sich selbst davor schützen würde, zu viel Ressourcen zu verbrauchen.

Ich habe das Problem mit DebugDiag gefunden.

Hier ist, wo ich begonnen: http://www.webdebug.net/index.php/2012/12/collect-iis-crash-dump-with-debugdiag/

I'd like to understand why an exception in an external DLL can cause the IIS application pool to shutdown, even if the exception is being caught inside the DLL and also when calling the DLL's method from within the code behind of the ASP.NET page.

Die externe DLL auch in Ihrem Anwendungspool ausgeführt. Ein schwerer Absturz in dieser DLL wird auch Ihren Anwendungspool zum Absturz bringen. Einige Ausnahmen können nicht behandelt werden, und die stackoverflow-Ausnahme gehört dazu. Thema wird diskutiert here. Vielleicht passiert es in Ihrem Fall.