2013-04-12 18 views
21

Przeczytałem posty ASP.NET application pool shutdown problem i IIS 7.5: problem with Application pool, ale nie odpowiedział na moje pytanie.Dlaczego moja pula aplikacji IIS7 wyłącza się po wystąpieniu wyjątku w bibliotece DLL wywoływanej ze strony ASP.NET?

Mam stronę C# ASP.NET, która w kodzie-behind tworzy instancję klasy z biblioteki DLL dostarczanej przez katalog BIN, a następnie wywołuje metodę dla tej instancji. Metoda wewnątrz biblioteki DLL rzuca System.ArgumentException ze względu na nieistniejącą kolumnę obiektu DataRow. Dziennik zdarzeń pokazuje następujący błąd:

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: 

kod wywołujący na stronie ASP.NET otacza wywołanie metody w ogólnej try-catch bloku. Kiedy żądam strony, powoduje to awarię odpowiedniej puli aplikacji mojej instancji IIS i moja strona internetowa nie jest już dostępna (błąd 503). Ręcznie muszę zrestartować pulę aplikacji i witryna działa ponownie.

Aktualizuj Zgodnie z wnioskiem bloku try catch z kodu ASP.NET za:

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

Teraz moje pytanie brzmi, dlaczego stosunkowo „proste” wyjątek takich jak System.ArgumentException wyrzucane podczas próby uzyskania dostępu do nieistniejąca kolumna DataRow, powoduje awarię całej witryny? Również ogólny blok try-catch strony ASP.NET nie pomaga, ani nie powinien to być powód, aby całkowicie uniemożliwić dostęp do całej witryny lub czy jest to błędne założenie? Nigdy bym nie pomyślał, że to może w zasadzie zabrać serwer (II).

W oczekiwaniu na ludzi, którzy mówią mi, że powinienem sprawdzić istnienie kolumny, zanim uzyskam do nich dostęp: wiem o tym i dotychczasowy kod został zmieniony, ale to nie jest moje pytanie, jak opisano powyżej, chciałbym wiedzieć, dlaczego konsekwencje są tak drastyczne.

Aktualizacja 2

Sposób pytanie miano wewnątrz DLL rozpoczyna wątek, który jest owinięty w try-catch bloku:

[...] 
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

Co dzieje się w bloku catch? Jeśli to spowoduje wyjątek, możesz mieć kłopoty. Czy możesz opublikować kod wypłaty? – levelnis

+0

Blok catch wywołuje metodę, która powoduje, że komunikat o błędzie jest widoczny dla klienta (przeglądarki), zaktualizuję moje pytanie. – Gorgsenegger

+0

Tylko po to, aby mnie zaskoczyć - jeśli całkowicie usuniesz blok try-catch i po prostu wywołasz metodę, czy pula aplikacji nadal się zawiesza? – levelnis

Odpowiedz

19

Najprawdopodobniej twoja pula aplikacji jest automatycznie wyłączana przez funkcję IIS's Rapid Fail Protection, jak zauważono w połączonych pytaniach. Jeśli sprawdzisz swój dziennik zdarzeń, może zostać wygenerowanych wiele nieobsługiwanych wyjątków w krótkim odstępie czasu.

Po prostu umieszczenie wystarczającej liczby nieobsługiwanych wyjątków w konfigurowalnym przedziale czasowym (domyślnie 5 na 5 minut) spowoduje wyłączenie AppPool, powodując odpowiedź 503 Service Unavailable.

Powodem tej funkcji jest to, że jeśli masz wadliwą aplikację, prawdopodobnie nie chcesz, aby była automatycznie uruchamiana ponownie przy każdym kolejnym żądaniu, zużywając zasoby i prawdopodobnie uszkadzając dane.

Muszę przyznać, że nie jest to zachowanie "domyślne", czego bym się spodziewał.

Zapoznaj się z Rick Stahls explanation, jest to trochę bardziej szczegółowe.

Aby to naprawić, musisz przechwycić wyjątek lub zapobiec wyjątkowi (tak jak sugeruje @leppie). Nieobsługiwane wyjątki mają zniszczyć cały proces wykonywania (co oznacza, że ​​pojedynczy proces żądania/procesu roboczego, a nie IIS) - sprawia, że ​​kod .Net jest znacznie łatwiejszy do debugowania, ponieważ nie ukrywa błędów lub po prostu nie zawiesza aplikacji.

Zauważ, że ten został zmieniony w .NET 2.0:
http://msdn.microsoft.com/en-us/library/ms228965.aspx
http://support.microsoft.com/kb/911816

Aktualizacja
Na podstawie powyższej aktualizacji, nie sądzę Twój Wyjątkiem jest rzeczywiście złapać, jeśli jest on wrzucony od CreateReport(). Ta metoda jest wykonywany w osobnym wątku:

exception still thrown

Musisz try-catch w ciele CreateReport() jeśli nie ma już jedno:

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

Dzięki za bardziej szczegółowe informacje, chociaż nadal nie rozumiem, dlaczego wyjątek *, który jest przechwytywany wewnątrz biblioteki DLL *, może spowodować zamknięcie puli aplikacji. Wielokrotne wyjątki wyrzucane w krótkim odstępie czasu również nie powinny mieć miejsca, ponieważ wykonanie metody DLL kończy się wraz z wyrzuceniem pierwszego wyjątku. Dziennik zdarzeń pokazuje również, że wygenerowano tylko jeden wyjątek. – Gorgsenegger

+0

@Gorgsenegger zaktualizował odpowiedź na podstawie Twojej opinii –

+0

Dziękuję, postaram się zweryfikować, gdy tylko znajdę czas - po prostu przenieśliśmy nasz TFS do innej sieci i wciąż jesteśmy w trakcie przywracania jej prędkości. , bardzo przepraszam za opóźnienie i proszę, zostańcie ze mną przez kilka dni. – Gorgsenegger

4

Zdarzyło mi się raz. Prawdziwy błąd (w moim przypadku) był przepełnieniem stosu, który zamykał pulę.

Wygląda na to, że IIS chronił się przed zużyciem zbyt dużej ilości zasobów.

Znalazłem problem za pomocą DebugDiag.

Tu zacząłem: 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.

dll zewnętrzny prowadzony również w swojej puli aplikacji. Poważna awaria tej biblioteki dll spowoduje również awarię puli aplikacji. Niektóre wyjątki nie mogą być obsługiwane, a wyjątek stackoverflow jest jednym z nich. Temat jest dyskutowany here. Być może tak właśnie jest w twoim przypadku.