web-dev-qa-db-ja.com

ASP.NETページから呼び出されたDLLの例外の後、IIS7アプリケーションプールがシャットダウンするのはなぜですか?

ASP.NETアプリケーションプールのシャットダウンの問題 および IIS 7.5:アプリケーションプールの問題 の記事を読みましたが、彼らは私の質問に答えませんでした。

BINディレクトリ経由で提供されるDLLのクラスをコードビハインドでインスタンス化し、このインスタンスのメソッドを呼び出すC#ASP.NETページを持っています。 DLL内のメソッドは、DataRowオブジェクトに存在しない列があるため、System.ArgumentExceptionをスローします。イベントログには、次のエラーが表示されます。

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: 

ASP.NETページの呼び出しコードは、メソッド呼び出しを汎用try-catchブロックにラップします。ページをリクエストすると、IISインスタンスの対応するアプリケーションプールがクラッシュし、Webサイトが利用できなくなります(エラー503)。手動でアプリケーションプールを再起動する必要があり、サイトは再び機能します。

Update要求に応じて、ASP.NETコードビハインドからのtry catchブロックを要求しました。

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

私の質問は、既存のDataRow列にアクセスしようとするとSystem.ArgumentExceptionなどの比較的「単純な」例外がWebサイト全体をクラッシュさせる理由です。 ASP.NETページの一般的なtry-catchブロックも役に立たず、これがWebサイト全体を完全に利用不能にする理由でもないのでしょうか、それとも間違った仮定ですか?これが基本的に(II)サーバーをダウンさせる可能性があるとは思いもしませんでした。

アクセスする前に列の存在を確認する必要があると人々に言われることを期待して:私はそれを知っており、レガシーコードは現在変更されていますが、これは上記の私の質問ではありません。なぜ結果はとても劇的です。

更新2

DLL内で呼び出される問題のメソッドは、try-catchブロックにラップされたスレッドを開始します。

[...]
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
}
22
Gorgsenegger

リンクされた質問でメモしたように、ほとんどの場合、アプリケーションプールは IISのRapid Fail Protection 機能によって自動的にシャットダウンされます。イベントログを確認すると、未処理の例外が複数連続してスローされている可能性があります。

簡単に言えば、構成可能なタイムスパンで十分な未処理の例外(デフォルトは5分で5)がAppPoolをシャットダウンし、503 Service Unavailable応答を引き起こします。

この機能の背後にある理由は、障害のあるアプリケーションがある場合、それ以降のすべてのリクエストで自動的に再起動され、リソースを消費し、データが破損する可能性がないためです。

これは私が期待していた「デフォルト」の動作ではないことを認めなければなりません。

Rick Stahlsの説明 を確認してください。もう少し詳しく説明します。

これを実際に修正するには、例外をキャッチするか、例外がスローされないようにする必要があります(@leppieが示唆するように)。未処理の例外は、実行中のプロセス全体(IISではなく、単一のリクエスト/ワーカープロセス)を破棄することになっています-エラーを隠したり、単にアプリケーションをハングさせたりしないため、.Netコードのデバッグがはるかに簡単になります。

これは.Net 2.0で変更されたことに注意してください。
http://msdn.Microsoft.com/en-us/library/ms228965.aspx
http://support.Microsoft.com/kb/911816

更新
上記の更新に基づいて、CreateReport()からスローされた場合、例外が実際にキャッチされるとは思わない。そのメソッドは別のスレッドで実行されています:

exception still thrown

まだない場合は、CreateReport()の本文にtry-catchが必要です。

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

それは一度私に起こりました。実際のエラー(私の場合)は、プールをシャットダウンするスタックオーバーフローでした。

IISは、リソースを消費しすぎないように自分自身を保護していたようです。

DebugDiagを使用して問題を見つけました。

私が始めた場所は次のとおりです。 http://www.webdebug.ne​​t/index.php/2012/12/collect-iis-crash-dump-with-debugdiag/

外部のDLLで例外が原因でIIS例外が=の内部でキャッチされている場合でも、アプリケーションプールがシャットダウンすることがある理由を理解したいDLLまた、ASP.NETページの背後にあるコード内からDLLのメソッドを呼び出す場合。

外部dllもアプリケーションプールで実行されます。このdllでの重大なクラッシュは、アプリケーションプールもクラッシュします。一部の例外は処理できず、stackoverflow例外もその1つです。件名は捨てられます こちら 。たぶんそれはあなたの場合に起こることです。

4
Guish