阻止Application_End事件的解決方案
在做項目時,遇到同步ERP數據的問題,客戶要求是:程序中,設置一個開始時間,再設置一個時間間隔,讓程序每隔一段時間導出銷售記錄,這個開始時間和時間間隔可以手動修改設定。
這問題糾纏了我好幾天,總算解決了,寫文檔記錄:
首先,要讓程序定時執行任務,可以使用ASP.NET中的Timer計時,不過這個定時不是很準,如果用它,還會遇到其他的問題,後麵會提到。第二種方法是,使用一個叫做:Quartz.NET開源項目,專門用來調度定時作業。
這次項目中,我用到的就是Quartz.NET組件,用他來定時調度作業,是很方便,不過問題也來了:當程序運行一段時間後,發現自動任務停止了。在網上查了查資料,說法不一。
後來多方查資料以及自己試驗證明:原來是網站應用程序在沒有請求時,過一定的時間就會停止應用程序,具體點來說,就是網站中的最後一個session結束時,網站應用程序就會結束。當然就會觸發Application_End事件。隨之定時任務也會停掉。
現在的問題就是:如何讓網站都有請求?如何讓Application_End事件不會發生?
這個問題在網上也有很多種說法,比如有人建議:在Application_End中用程序模擬請求網站,重新開始Application_Start事件,也給出了程序代碼:https://asdfblog.com/technology/aspnet-scheduled-tasks-with-quartznet.html這裏有詳細說明。不過我照博主的做法,並沒有實現我想要的功能。不過他是用來處理IIS應用程序池回收的問題的。
孟子E章說:新建一個獨立的線程來調度執行的任務,個人認為比較麻煩,沒采用這種方式。
最後,發現了一個簡單的處理方式,利用ASP.NET的緩存超時技術。下麵具體來闡明,基本思路:
在應用程序啟動時,用程序緩存一個網站中的頁麵。在緩存網頁時,設置好緩存過期時間,以及緩存過期時觸發的回調事件,緩存過期時觸發的回調事件這是關鍵。在緩存過期時用程序模擬請求網站頁麵,再次緩存,循環之…
代碼說明:(全在Global.asax裏)
private const string DummyPageUrl = "http:/index.aspx";
private const string DummyCacheItemKey = "GagaGuguGigi";
Quartz.IScheduler sched = SingletonScheduler.GetIntance();
void Application_Start(object sender, EventArgs e)
{
//緩存頁麵
RegisterCacheEntry();
}
// 注冊一緩存條目在5分鍾內到期,到期後觸發的調事件
private void RegisterCacheEntry()
{
if (null != HttpContext.Current.Cache[DummyCacheItemKey]) return;
HttpContext.Current.Cache.Add(DummyCacheItemKey, "Test", null, DateTime.MaxValue,
TimeSpan.FromMinutes(5), 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_BeginRequest(Object sender, EventArgs e)
{
if (HttpContext.Current.Request.Url.ToString() == DummyPageUrl)
{
RegisterCacheEntry();
}
}
這樣,網站應用程序就可以像運行windows服務一樣,在後台默默的執行了,沒看明白,可以參見這裏:https://www.codeproject.com/KB/aspnet/ASPNETService.aspx
附:Quartz.Net詳細教程參見:
①官方教程:https://quartznet.sourceforge.net/tutorial/index.html;
②中文翻譯:https://www.cnblogs.com/shanyou/category/102991.html
====================================2013-8-2 後記================================================
在WebForm中使用Quartz.Net組件,個人測試結果,感覺也不夠穩定,最終是由 Winform客戶端程序+Quartz.NET組件實現,程序一直放在服務器上跑著。
為了防止服務器端程序停掉,可以寫成windows服務,這樣服務器一啟動,就會執行任務,隻要服務器沒停,程序也會一直運行。
當然,這隻能適用於獨立主機,虛擬空間就不行了。
附:
1.如何編寫windows服務:
https://msdn.microsoft.com/zh-cn/library/vstudio/9k985bc9.aspx
https://www.cnblogs.com/tuyile006/archive/2006/11/27/573654.html
2.windows服務輔助類:https://blog.csdn.net/a497785609/article/details/9103129
最後更新:2017-04-02 06:51:29