1. ホーム
  2. .net

[解決済み】Response.End()は有害とみなされるか?

2022-04-13 22:37:05

質問

このKBの記事 によると、ASP.NETの Response.End() はスレッドを終了させます。

Reflectorで見ると、こんな感じ。

public void End()
{
    if (this._context.IsInCancellablePeriod)
    {
        InternalSecurityPermissions.ControlThread.Assert();
        Thread.CurrentThread.Abort(new HttpApplication.CancelModuleException(false));
    }
    else if (!this._flushing)
    {
        this.Flush();
        this._ended = true;
        if (this._context.ApplicationInstance != null)
        {
            this._context.ApplicationInstance.CompleteRequest();
        }
    }
}

これはかなり厳しいと思われます。 KBの記事にあるように、アプリ内の次のコードはすべて Response.End() は実行されないので、最小驚嘆の原則に違反することになります。それは、ほとんど Application.Exit() WinFormsアプリで によって引き起こされるスレッド中断例外は Response.End() はキャッチできないので、コードを try ... finally では満足できない。

を常に避けるべきかと考えさせられます。 Response.End() .

どのような場合に Response.End() というのは Response.Close() および HttpContext.Current.ApplicationInstance.CompleteRequest() ?

を参照してください。 リック・ストロールのブログエントリー .


いただいたご意見をもとに、私の答えを。 そうですね。 Response.End は有害である しかし、限られたケースでは有効です。

  • 使用 Response.End() をキャッチ不能なスローとして、即座に終了させます。 HttpResponse 例外的な状況下で デバッグの際にも便利です。 避けるべきこと Response.End() ルーチンの応答を完了するために .
  • 使用 Response.Close() を使用すると、クライアントとの接続を直ちに終了させることができます。 について このMSDNブログの記事 このメソッドは は、通常の HTTP リクエスト処理用ではありません。 このメソッドを呼び出す正当な理由があるとはとても思えません。
  • 使用 CompleteRequest() で通常のリクエストを終了します。 CompleteRequest は、ASP.NETパイプラインを先にジャンプさせて EndRequest イベントの後に、現在の HttpApplication イベントが終了します。 ですから、もしあなたが CompleteRequest を実行した後、レスポンスにさらに何かを書き込むと、その書き込みはクライアントに送信されます。

編集部 - 2011年4月13日

さらにわかりやすく、こちらでご紹介しています。

どのように解決するのか?

アプリに例外ロガーを採用していた場合、その例外ロガーは ThreadAbortException を、これらの穏やかな Response.End() を呼び出します。 これは、マイクロソフト流の「いい加減にしろ!」ということなのでしょう。

私なら Response.End() は、何か例外的な条件があり、他のアクションが不可能な場合に使用します。 その場合、この例外をログに記録することで、実際に警告を示すことができるかもしれません。