2011-09-01 14 views
10

をリサイクルする際の検出。ASP.NETアプリケーションは、私はASP.NETアプリケーションは、web.configファイルが変更されているか、IISのアプリケーションプールを手動で再利用されているいずれかのためにリサイクルされたときを検出しようとしている

は当初、私は、ASP.NETのApplication_End方法が働くだろうと思って、次のことを試してみました:

protected void Application_End(object sender, EventArgs e) 
{ 
    File.AppendAllText("log.txt", DateTime.Now + "\n"); 
} 

ファイルは、web.configファイルが変更されたときに初めて作成されましたが、それ以降の変更は発生しませんでしたイベント。同様に、IISでテストする場合、最初の手動アプリケーションプールリサイクルでファイルが作成されましたが、後で実行されたリサイクルでは作成されませんでした.Apple_Endイベントが1回だけ実行されるようになります。

プール/アプリがリサイクルするたびにどのように検出されますか?

+6

Application_Startを使用していますか?私はシャットダウンや停電のようないくつかのイベントは、あなたがApplication_Endが呼び出されたときに知らせてくれないと思います。 –

+1

web.configファイルを変更した後、アプリケーション内のページにアクセスしたことを確認したので、終了してから再開しましたか?なぜなら、それが再び始まらなければ、Application_Endが後で発射するのを防ぐことができるからです。 – StriplingWarrior

答えて

4

以下は、ハックの少しかもしれないが、あなたはそれを把握するために、アプリケーションCacheを使用することができます。ページが読み込まれるたびに特定のキーのキャッシュをチェックできます。キーが存在しない場合は、それを「リサイクル」と見なしてからキーを追加できます。最良の方法ではありませんが、あなたが必要とするものだけで動作するかもしれません。

例:すべてのリクエストで実行されますあなたのベースページのPage_Loadどこかで、次の操作を行うことができます:リサイクルが起こるように

if (HttpContext.Current.Cache["RecycleCheck"] != null) 
{ 
    // Add flag to cache 
    HttpContext.Current.Cache.Insert("RecycleCheck", "1", null, 
     DateTime.UtcNow.AddDays(2), // 2 days (most will recycle by then) 
     System.Web.Caching.Cache.NoSlidingExpiration); 

    // Do what you need because a recycle has happened 
} 

この方法は、それを拾うことはありません。リサイクル後の最初のリクエストでリサイクルのみを識別します。

Application_Startはこれを行うには最も信頼できる場所ですが、最初のリクエストでリサイクルした後にハックと同じ問題が発生します。

+1

これは 'Application_Start'が解決しないものを解決しますか? – TheCodeKing

+0

@TheCodeKingそれは実際には、私が(私の答えの最後の行に気付いた)理由は、 'Application_Start'が最適な場所だと言います。なんらかの理由で問題があって、 'Application_End'と' Start'がトリガーされない場合にのみ、これはハッキーな選択肢です。 – Kelsey

+1

これはちょうど 'Application_Start'が**常に**呼び出されるようになっています。アプリケーションのリサイクルでは使用できない' Application_End'だけです。 – TheCodeKing

0

なぜこのようなことをしないのですか?タイマージョブの頻度を調整して、appPoolのリサイクル時期を判断する精度を向上させます。

private readonly Timer timer = new Timer(); 
private DateTime start; 
private string logFile; 

void Application_Start(object sender, EventArgs e) 
{ 
    start= DateTime.Now; 
    logFile = Server.MapPath(
      string.Concat("Log-",start.ToString("yyyyMMdd-HHmmss.fff"),".txt")); 

    timer.Interval = 1000; 
    timer.Elapsed += (s, ee) 
      => File.WriteAllText(logFile, 
      string.Concat("App Start :", start, " Last Alive: ", DateTime.Now)); 

    timer.Start(); 
} 
2

この質問に良い答えは、次のスタックオーバーフローの質問に提供された:あなたはIRegisteredObjectインターフェイスを実装する必要がリサイクルアプリケーションプールを追跡するにhow to detect if the current application pool is winding up

、あなたのインスタンスを作成するためにApplicationManager.CreateObjectを呼び出しますオブジェクトを作成し、アプリケーションの起動時にHostingEnvironment.RegisterObjectに登録します。

このオブジェクトのIRegisteredObject.Stop(bool)実装がパラメータとしてfalseを指定して呼び出された場合、これはアプリケーションドメインがシャットダウンされていること、および(グローバルディスポーザのような) HostingEnvironment.UnregisterObjectを呼び出します。

ので、アプリケーションプールがリサイクルされるときに追跡することができ、このイベントを使用しました。

関連する問題