前言
項目中使用了Quartz.Net 作為任務調度框架,執行定時任務功能,任務的開始和結束放在Application_Start和Application_End中調用,因為IIS的應用程序池自動回收導致某些時間(無用戶訪問導致沒有請求到Application_Start 觸發任務開始)定時任務執行失敗,下面對解決方式做一個記錄。
方案一
修改IIS程序池的回收設置的 固定時間間隔和 進程模型的閑置超時 設置為0 (不推薦)
或者根據用戶使用時間設置一個合理的回收時間間隔 如 用戶可能下班后(18:00)不再訪問站點,而夜間一點要執行一個定時作業,則設置閑置超時為8*60=480分鍾
方案二
在站點中設置定時請求站點,不觸發閑置超時,保證始終有請求發送到站點
/**Global.asax**/
private static string DummyPageUrl = ConfigurationManager.AppSettings["RefreshUrl"].ToString();//可訪問的頁面
private static string RefreshTime = ConfigurationManager.AppSettings["RefreshTime"].ToString();
private const string DummyCacheItemKey = "CallWebsite";
// 注冊一緩存條目在RefreshTime分鍾內到期,到期后觸發的調事件 RefreshTime 要小於站點應用程序池的閑置超時時間
private void RegisterCacheEntry()
{
if (null != HttpContext.Current.Cache[DummyCacheItemKey]||!int.TryParse(RefreshTime,out int minute))
return;
HttpContext.Current.Cache.Add(DummyCacheItemKey, "r", null, DateTime.MaxValue,
TimeSpan.FromMinutes(minute), CacheItemPriority.NotRemovable,
new CacheItemRemovedCallback(CacheItemRemovedCallback));
}
// 緩存項過期時程序模擬點擊頁面,阻止應用程序結束
public void CacheItemRemovedCallback(string key, object value, CacheItemRemovedReason reason)
{
HitPage();
}
// 模擬點擊網站網頁
private void HitPage()
{
System.Net.WebClient client = new System.Net.WebClient();
client.DownloadData(DummyPageUrl);
}
protected void Application_Start()
//IIS超過空閑時間會回收導致定時停止,這里采用定時訪問站點的方式,阻止站點進行回收
RegisterCacheEntry();
}
protected void Application_BeginRequest(Object sender, EventArgs e)
{
if (HttpContext.Current.Request.Url.ToString() == DummyPageUrl)
{
RegisterCacheEntry();
}
}
<!--Web.config-->
<app key="RefreshUrl" value="localhost:9000/controller/action?refresh=1"/>
<app key="RefreshTime" value="19"/>
方案三
將任務調度框架做成Windows服務項目,安裝到服務器上,定時請求API執行任務完成功能。
結語
以上就是解決IIS程序池定期回收導致定時作業不執行的方案了,如有問題還請指正。
附錄
參考文章 c#解決應用池自動回收的方法