2011-09-01 23 views
10

我試圖檢測ASP.NET應用程序何時回收,因爲要修改web.config文件或手動回收IIS應用程序池。檢測ASP.NET應用程序何時回收

起初我還以爲ASP.NET的Application_End方法將工作,並嘗試以下操作:

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

該文件第一次創建的web.config文件被更改,但隨後的變化不火的事件。同樣,在IIS中進行測試時,第一個手動應用程序池回收創建了該文件,但後來沒有 - 這就好像Application_End事件只發生過一次。

如何檢測每次池/應用程序回收?

+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

好這個問題的答案在下面的堆棧溢出問題提供了:how to detect if the current application pool is winding up

要跟蹤應用程序池回收您需要實現IRegisteredObject接口,調用ApplicationManager.CreateObject創建的實例你對象,然後在應用程序啓動過程中將其註冊到HostingEnvironment.RegisterObject。

當此對象的IRegisteredObject.Stop(bool)實現以false作爲參數調用時,這是通知應用程序域正在關閉並且該對象應該被註銷(有點像全局配置)調用HostingEnvironment.UnregisterObject。

因此,使用此事件您可以跟蹤應用程序池何時回收。

相關問題