2012年3月16日 星期五

ASP.NET 定時任務與IIS應用程序回收

研究動機

最常見是「電子報」的定時寄送,在ASP.NET應用裏,我們通常會建立一個Windows Service來負責定時的電子報寄送服務,但每次佈署網站時得需要管理員權限來佈署這服務。其實,ASP.NET應用程式可以透過Global.aspx中的定義來執行定時計劃性任務,實作方式很簡單(加入一個Timer即可),但它會遇到iis的應用程序定時回收機制(預設是每29個小時),即會停止運作。解決的方式可詳看這篇文章: asp.net計劃任務-解決應用池回收問題。整個技術的重點在於掌握Timer失去功效的時機,為此我作了一番測試與驗證,才敢正式使用。

Timer執行時機

原文沒把timer物件的宣告等級調為全域,隨時有可能被回收: 
Image


原本要用EventLog寫入事件記錄,但ASP.NET在安全等級不允許,因此我使用一個I/O Log來記錄timer觸發的時機點。 
Image

IIS回收時機

IIS管理員中,你可以隨時停止一個虛擬子網站的運行: 
Image

然而,它只是阻止Web Client連線,並不會影響該Web程式的內應用程序,只有透過Browse該網站,才會啟動Application_Start()函式。每個ASP.NET應用程式都會對映到其「應用程式池」,它預設29小時會回收所衍生的程序(取消定時回收並不是一個好的主意): 
Image

這個回收程序執行時,就會觸發Application_End()函式,並停止所有運作,等到有人再Browse該網站任一頁,才會再啟動Application_Start()函式。 因此我們若要維持timer不中斷,就必須在End函式中,再去觸發browse網站任一頁。 
Image

當你要手動執行回收時,在「應用程式集區」按右鍵: 
Image

本文結論

這篇文章探討IIS觸發Web應用程式的Application_Start()與End()時機,唯有充份了解,才能掌握Timer計劃性任務的確切執行。

沒有留言:

張貼留言