global.asax でリサイクル イベントをキャッチすることはできますか?
Application_End がトリガーされることはわかっていますが、それがアプリケーション プールのリサイクルによってトリガーされたことを知る方法はありますか?
thx、Lieven Cardoen aka Johlero
global.asax でリサイクル イベントをキャッチすることはできますか?
Application_End がトリガーされることはわかっていますが、それがアプリケーション プールのリサイクルによってトリガーされたことを知る方法はありますか?
thx、Lieven Cardoen aka Johlero
Scott Guthries のブログで次の記事を見つけました。
ASP.NET アプリケーション シャットダウン イベントのログ記録
listserv の誰かが最近、ASP.NET がアプリケーション ドメインを再起動する理由と時期を特定する方法があるかどうかを尋ねました。具体的には、彼は、本番環境の共有ホスト環境で自分のアプリケーションでそれらを引き起こした正確な原因を探していました (web.config ファイルの変更、global.asax の変更、app_code ディレクトリの変更、ディレクトリの削除の変更、最大-num-compilations がクォータに達した、\bin ディレクトリの変更など)。
私のチームの Thomas は、彼が書いたクールなコード スニペットを持っています。再利用して任意のアプリケーションに追加するのは非常に簡単で、必要な場所に情報を記録するために使用できます (以下のコードは NT イベント ログを使用して保存しますが、データベースや管理者への電子メールを介して)。このコードは、ASP.NET V1.1 と ASP.NET V2.0 の両方で機能します。
System.Reflection および System.Diagnostics 名前空間を Global.asax クラス/ファイルに追加し、次のコードで Application_End イベントを追加します。
public void Application_End() {
HttpRuntime runtime =
(HttpRuntime) typeof(System.Web.HttpRuntime).InvokeMember("_theRuntime",
BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.GetField,
null, null, null);
if (runtime == null)
return;
string shutDownMessage =
(string) runtime.GetType().InvokeMember("_shutDownMessage",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField,
null, runtime, null);
string shutDownStack =
(string) runtime.GetType().InvokeMember("_shutDownStack",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField,
null, runtime, null);
if (!EventLog.SourceExists(".NET Runtime")) {
EventLog.CreateEventSource(".NET Runtime", "Application");
}
EventLog log = new EventLog();
log.Source = ".NET Runtime";
log.WriteEntry(String.Format(
"\r\n\r\n_shutDownMessage={0}\r\n\r\n_shutDownStack={1}",
shutDownMessage, shutDownStack),
EventLogEntryType.Error);
}
そこで、これがどのように機能するかについてのアイデアを次に示します。
以前の回答(AppDomain.CurrentDomain.ProcessExit に添付) とstephbuのコメントに基づいて:
これにより、構造化されたプロセスのティアダウンなどのほとんどがトラップされますが、すべてのティアダウンがトラップされるかどうかはわかりません。例 http://blogs.msdn.com/jmstall/archive/2006/11/26/process-exit-event.aspx プロセス リサイクルは、ハングしているように見える場合、プロセスを強制終了します。ハンドラーは呼び出されません。
次の戦略を提案します。
(通常の) ProcessExit ハンドラー (アプリケーション プールのリサイクルでは呼び出されないと想定されます) で、" app_domain_end_ok.tmp
" のようなファイルをディスクに書き込みます。
次に、global.asax の Application_Start で、このファイルを確認します。存在しない場合は、アプリケーションが正常に終了されていないことを示しています (または、アプリケーションが初めて起動したことを示しています)。チェック後、このファイルをディスクから削除することを忘れないでください。
私自身は試していませんが、試してみる価値はあります。
私はこれを自分で試したことはありませんが、イベント ハンドラーを AppDomain の ProcessExit イベントにアタッチしてみてください。
...
AppDomain.CurrentDomain.ProcessExit += new EventHandler(OnExit);
...
void OnExit(object sender, EventArgs e) {
// do something
}
これが役立つことを願っています!
DomainUnload イベントにアタッチすることで、はるかに成功しました。これは、AppPool のリサイクルと AppPool 自体の停止でトリガーされます。
AppDomain.CurrentDomain.DomainUnload += this.CurrentDomainOnProcessExit;