(別の投稿のコメントで)Response.Redirect() を呼び出すと、ThreadAbortException がスローされ、OnPreRender() イベントが呼び出されないため、問題が発生することがわかります。それでは、代わりにこれを使用してみませんか?:
Response.Redirect("~/SomePage.aspx", false);
そこに表示される「false」は、ページの実行がすぐに終了するかどうかを示します。デフォルトでは、Response.Redirect() は「true」を使用します。OnLoad() イベントに必要なものがすべて含まれるように OnPreRender() イベントを実行する必要がある場合は、「false」に設定し、Response.Redirect を呼び出した後に Page_Load() の最後にジャンプするようにしてください。 () または実行後に実行されるコードは実行しても問題ありません。
おそらく、オーバーロードされた Response.Redirect() メソッドを使用して「false」を渡すという考えが気に入らないので、そのルートに行かなかったのです。ここにあなたの心を揺さぶるのに役立つかもしれないいくつかのドキュメントがあります:
Microsoft は、「true」を指定すると HttpResponse が呼び出されるため、「endResponse パラメーターに false を渡すことをお勧めします」と述べています。元のリクエストのEnd() メソッドを呼び出し、完了時に ThreadAbortException をスローします。Microsoft は続けて、「この例外は Web アプリケーションのパフォーマンスに悪影響を及ぼします」と述べています。ここの「備考」セクションを参照してください: http://msdn.microsoft.com/en-us/library/a8wa7sdt.aspx
これは昨年 MSDNに投稿されました。
End メソッドも、私の「絶対に使用しない」リストに含まれています。リクエストを停止する最善の方法は、HttpApplication.CompleteRequest を呼び出すことです。End メソッドが存在するのは、1.0 がリリースされたときに従来の ASP との互換性を維持しようとしたためです。従来の ASP には、ASP スクリプトの処理を終了する Response.End メソッドがあります。この動作を模倣するために、ASP.NET の End メソッドは ThreadAbortException を発生させようとします。これが成功すると、呼び出し元のスレッドは中止され (非常にコストがかかり、パフォーマンスが低下します)、パイプラインは EndRequest イベントにジャンプします。もちろん、ThreadAbortException が成功した場合は、それ以上コードを呼び出す前にスレッドがアンワインドすることを意味するため、End を呼び出すと、その後はコードを呼び出さないことを意味します。End メソッドが ThreadAbortException を発生させることができない場合、代わりに応答バイトをクライアントにフラッシュしますが、これを同期的に行うためパフォーマンスが非常に悪く、End の後のユーザー コードの実行が完了すると、パイプラインは EndRequest 通知にジャンプします。クライアントへのバイトの書き込みは、特にクライアントが地球の反対側にあり、56k モデムを使用している場合、非常にコストのかかる操作です。したがって、バイトを非同期で送信するのが最善です。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。しかし、これは同期的に行われるため、パフォーマンスが非常に悪く、End の後のユーザー コードの実行が完了すると、パイプラインは EndRequest 通知にジャンプします。クライアントへのバイトの書き込みは、特にクライアントが地球の反対側にあり、56k モデムを使用している場合、非常にコストのかかる操作です。したがって、バイトを非同期で送信するのが最善です。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。しかし、これは同期的に行われるため、パフォーマンスが非常に悪く、End の後のユーザー コードの実行が完了すると、パイプラインは EndRequest 通知にジャンプします。クライアントへのバイトの書き込みは、特にクライアントが地球の反対側にあり、56k モデムを使用している場合、非常にコストのかかる操作です。したがって、バイトを非同期で送信するのが最善です。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。パイプラインは EndRequest 通知にジャンプします。クライアントへのバイトの書き込みは、特にクライアントが地球の反対側にあり、56k モデムを使用している場合、非常にコストのかかる操作です。したがって、バイトを非同期で送信するのが最善です。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。パイプラインは EndRequest 通知にジャンプします。クライアントへのバイトの書き込みは、特にクライアントが地球の反対側にあり、56k モデムを使用している場合、非常にコストのかかる操作です。したがって、バイトを非同期で送信するのが最善です。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。これは、リクエストが通常の方法で終了したときに行うことです。同期的にフラッシュするのは本当に悪いです。要約すると、End を使用するべきではありませんが、CompleteRequest を使用してもまったく問題ありません。End のドキュメントには、EndRequest 通知にスキップして要求を完了するには、CompleteRequest の方が適していると記載されている必要があります。
MSDN が示唆するように、Response.Redirect() を呼び出した後にこの行を追加したところ、すべてが同じように実行されているように見えました。4.0 で必要かどうかはわかりませんが、問題はないと思います。
HttpContext.Current.ApplicationInstance.CompleteRequest();
更新 1
Response.Redirect() の呼び出しで "false" を使用すると、ThreadAbortException を回避できますが、ページでスローされる可能性があるその他の未処理の例外はどうでしょうか? これらの例外により、OnPreRender() なしで OnUnload() が呼び出されるという問題が引き続き発生します。誰もがこれを回避するように提案しているように、OnPreRender() でフラグを使用できますが、ハンドルされていない例外をスローしている場合は、より大きな問題が発生しており、とにかくエラー ページにリダイレクトする必要があります。Unhandled Exceptions はすべてのポストバックでスローする予定のものではないため、Try-Catch で OnUnload() ロジックをラップした方がよいでしょう。例外をログに記録して監視している場合は、OnUnload() イベントで NullReference 例外をログに記録する直前に未処理の例外がスローされていることがわかり、どれを無視するかがわかります。
更新 2
OnUnload() を Try-Catch でラップしたままにする必要がありますが、これが本当に探しているものだと思います (Response.Redirect を呼び出すとき、または Unhandled Exception の後にエラー ページにリダイレクトするときに IsRequestBeingRedirected が true になることを思い出してください)。 .:
if (HttpContext.Current.Response.IsRequestBeingRedirected != true)
{
//You're custom OnUnload() logic here.
}
これにより、OnUnload() イベントでカスタム ロジックを処理することが安全かどうか (または処理する価値があるかどうか) がわかります。おそらくこれで始めるべきだったと思いますが、今日は多くのことを学んだと思います。;)
注: Server.Transfer() を使用すると、恐るべき Response.End() も呼び出されます。これを回避するには、代わりにpreserveForm属性を「false」に設定して Server.Execute() を使用します。
Server.Execute("~/SomePage.aspx", false);
return;
注: Server.Execute("~/SomePage.aspx", false); に関すること IsRequestBeingRedirected は false になりますが、OnPreRender() は引き続き実行されるため、心配する必要はありません。