asp.net アプリケーションが ThreadAbortException をスローするのはなぜですか?
-
08-06-2019 - |
質問
自明の質問。
何も問題がないのに、なぜこのことが私のトライキャッチに混入するのでしょうか?
ログに何百回も表示されるのはなぜですか?
新しい質問なのはわかっていますが、このサイトが検索ランキングを獲得して初心者を呼び込むつもりなら、彼らに尋ねる必要があります。
解決
これはおそらく Response.Redirect 呼び出しからのものです。説明については、このリンクを確認してください。
http://dotnet.org.za/armand/archive/2004/11/16/7088.aspx
(ほとんどの場合、Response.Redirect(url, false) を呼び出すと問題は解決します)
他のヒント
ThreadAbortException の最も一般的な理由は、 Response.End、Response.Redirect、または Server.Transfer. 。Microsoft は、これらの関数の代わりに使用する必要があるいくつかの推奨関数を公開しています。
他の人が言ったように、これは Response.End() を呼び出すと発生します (2 番目のパラメータとして false を渡さずに Response.Redirect を呼び出すと発生します)。これは設計どおりに機能しています。通常、Response.Redirect を呼び出す場合は、リダイレクトをすぐに実行する必要があります。詳細については、これを参照してください。
内部で使用する API が (少なくとも) 3 つあることを知っている Thread.Abort
, 、どうすればよいのか、より実践的な観点からお答えしたいと思います。
私たちの場合、このエラーは突然ログに記録され始めました。何が変わったのでしょうか?サイトマップを処理する一部のデータベース プロシージャのバグを修正しました。
log4net のログには、X-Forwarded-For ヘッダー (NLB の背後にあります) が Googlebot の IP アドレス 66.249.78.x であることが示されており、サイトマップの変更により Google がサイトをより積極的にクロールして画像を探しているという私の理論が裏付けられました。
まず最初に、なぜ Googlebot だけがこの問題を引き起こすことができたのかを解明することでした。他のクライアントはコードパスが使用するものをトリガーしていませんでした Response.Redirect
, 、または何でも。
それで、 HttpApplication.Error
ハンドラーに、すべてのヘッダーとほとんどのデータを含む詳細な出力をログに記録するコードをいくつか追加しました。 HttpResponse
そして HttpContext
ログに吐き出されました。
これにより、Googlebot が iPhone ユーザー エージェント文字列を使用していることが問題であることがわかり、それを利用してコードベースで「iPhone」を検索し、次の結果を見つけることができました。
private void CheckIPhoneAccess() { ... }
そして、それはリダイレクトを使用します。
それについてどうすればよいでしょうか?
まあ、この古いコードベースでは、すべてのコードにレトロパッチを適用する価値はありません。 Response.Redirect
呼び出しのため、ログレベルを下げます。 ThreadAbortException
アプリケーション用。
Googlebot のモバイル クローラーの動作を変更します。 ない 最初のヒット時にのみリダイレクトされ、その後は Cookie を読み取って画像を表示するため、当社のサイトがモバイルに提供するものについての「嘘」につながります。Googlebot はその Cookie をキャッシュしていないようです。
完璧ではありませんが、サイトは再構築される予定です。おそらく Scala か何かを使用している別のチームによるものなので、実用的な観点からは、これは良い選択だと思います。コメントを追加し、後で問題を再検討する可能性があります。 Response.SafeRedirect
このアドバイスをカプセル化する拡張機能:
Response.Redirect によって System.Threading.ThreadAbortException が発生するのはなぜですか?
ルーク
Response.Redirect がこの例外を与える理由は、asp.net が Thread.Abort() を使用してこの API を内部的に実装しているためです。このメソッドが呼び出されると、特別な ThreadAbortException がスローされます。この例外はどの catch ブロックにも飲み込まれません。各キャッチ ブロックの最後に再スローされます。