2017-10-18 11 views
1

なぜコードが動作しないのかわかります。私は技術的な理由がそれを作るのか分かりませんので、より明示的なエラーメッセージが出ません。なぜIISが循環コンストラクタで "502.3 - Bad Gateway"エラーを返すのですか

netcore2アプリケーションを開発しているうちに、コンストラクタを使用して循環参照を作成しました。私は、クラスAのコンストラクタが、タイプAのオブジェクトをインスタンス化するなど、タイプBの他のオブジェクトをインスタンス化することを意味します。

ここには、その例を作成したonline compilerStackOverflowExceptionをスローする循環インスタンス化を再現するための簡単なコードスニペットがあります。

public class A 
{ 
    public A() 
    { 
     var b = new B(); 
    } 
} 

public class B 
{ 
    public B() 
    { 
     var b = new B(); 
    } 
} 

public class Program 
{ 
    public static void Main(string[] args) 
    { 
     var a = new A(); 
    } 
} 

驚くべきことに、代わりにstackoverflowの例外のそれは根本的な問題についての多くの情報が得られない、IIS、右のアプリケーションがクラッシュする前に、私を与えること502.3 - Bad Gatewayエラーです。私はこのような循環呼び出しが、コンパイラによって捕捉されるだけでなく、VisualStudio 2017またはResharperの究極のピンポイントでも検出できるほど簡単なパターンであると期待していましたが、何も警告しませんでした。

this articleなどthis one問題がタイムアウトすることができたことを示すように見えるが、アプリケーションが2秒の下でクラッシュするので、それは考えにくいです。

私は単純になぜCircularConstructionExceptionが理解できないのですか?これは実装が簡単で、さらに悪くても、IISがオンラインコンパイラのように普通のStackOverflowExceptionを投げないのはなぜですか?

+1

502.3も例外ではありません。実際の例外は、StackOverflowExceptionである可能性があります。 502.3はIISからのものではないかもしれません。あなたとIISの間のプロキシから来ている可能性があります。 –

+1

問題があるかどうかわかりませんが、これはデバッグモードではローカルにあります。スローされたすべての他の例外について、私は詳細の例外ページを取得します。なぜこのケースでは例外が隠されているのですか?私はアプリのクラッシュ(ループから抜ける方法)がなぜStackOverflowなのか、それともデバッグモードになっている間に実際にスローされた例外がIISによって隠されているのか理解できますか? – Wndrr

答えて

3

私は正しい答えは、それがC#の設計上の決定だと考えています。あなたのケースでは、他の例外がキャッチされて例外ページにラップされますが、StackOverflowExceptionはプロセスを終了させます。これは、502.3応答を報告する理由です(接続エラーを報告します)。 MSDNのページから


StackOverflowExceptionのS:.NET フレームワークの以前のバージョンで

、あなたのアプリケーションが 無限の再帰から回復するために、例えば(StackOverflowExceptionがオブジェクト をキャッチすることができ)。重要な追加のコードが確実にスタック オーバーフロー例外をキャッチし、 プログラムの実行を継続するために必要な あるのでしかし、 練習が現在であること を落胆。 .NET Frameworkの バージョン2.0以降で

、StackOverflowExceptionが オブジェクトはのtry-catch ブロックでキャッチすることができず、対応するプロセスは、デフォルトで終了 です。したがって、 ユーザは、 というコードを書き込んで、スタックを検出して防止することをお勧めします。 オーバーフロー。たとえば、 アプリケーションが再帰に依存する場合は、 カウンタまたは状態条件 を使用して再帰ループを終了します。 共通言語ランタイム(CLR)をホストするアプリケーションで、 オーバーフロー例外が発生したアプリケーションドメインの アプリケーションドメインをCLRでアンロードして、 の対応するプロセスを続行するように指定できます。 詳細については、 ICLRPolicyManagerインターフェイスおよび 共通言語ランタイムのホストを参照してください。

+0

適切なMSDNページへのポインタをありがとうございます。それは本当にこの方法であることを意味します。私はMSDNのページに言及している 'ICLRPolicyManager'に向かって詳しく調べます。 – Wndrr

0

このクラスitsef不定詞の時間を呼び出すと、スタックオーバーフロー

public class B 
{ 
    public B() 
    { 
     var b = new B(); 
    } 
} 
+0

あなたの声明は本当ですが、これは質問に答えません。とにかくお時間をありがとうございます:-) – Wndrr

1

を引き起こして何CircularConstructionExceptionはありませんなぜ私は単純に理解していない - これは

ありますを実装するために十分に簡単に聞こえます実行時に別のオブジェクトをインスタンス化するオブジェクトについて、たとえ同じ型であっても違法ではありません。問題はスタックを適切に制御していないことにあり、実際にはStackOverflowExceptionが適切です。この場合、問題はおそらくコンパイラによって検出される可能性がありますが、それは実行時の例外ではありません。

さらに悪いことに、IISがオンラインコンパイラのような通常のStackOverflowExceptionをスローしないのはなぜですか?

IISは、なぜそれが死亡したのかわかりません。アプリを実行するワーカープロセスを作成します。そのプロセスはスタックのオーバーフローのために終了しました。 IISホストプロセスは、ワーカープロセスが失敗したことを示すエラーを返しました。たぶん "Bad Gateway"が最も明確ではないかもしれませんが、IISホストはスタックのオーバーフローについて何も知らないでしょう。それは、そのワーカープロセスが応答していないか、または死んでいることを知っているだけです。

+0

IISの内部動作についてのさらなる説明をありがとうございました。私は2つの答えを正しいものとしてマークしたいと思います。 – Wndrr

関連する問題