[toc] 基於Coravel定時任務之計算總頁數 1 應用背景 在物聯網系統中,需要計算底端所有設備的總數,除以分頁每頁顯示數量,進行一個總頁數的顯示。包括狀態,告警,日誌等等數據都需要對應的總頁數的顯示。 2 對比各家定時庫 2.1 TaskScheduler TaskScheduler庫只支持 ...
目錄
基於Coravel定時任務之計算總頁數
1 應用背景
在物聯網系統中,需要計算底端所有設備的總數,除以分頁每頁顯示數量,進行一個總頁數的顯示。包括狀態,告警,日誌等等數據都需要對應的總頁數的顯示。
2 對比各家定時庫
2.1 TaskScheduler
TaskScheduler庫只支持.net,且需要結合windows任務計劃程式來調用,pass。
2.2 Fluent Scheduler
Fluent Scheduler只支持.net,pass。
2.3 Quartz.net
本身框架太重,而且使用複雜,pass。
2.4 Hangfire
相對Quartz輕量很多,使用也簡單,而且有網頁可以訪問來觀察任務執行情況,但是有一個致命的缺點就是只能支持分鐘及以上的定時任務處理原因在於Hangfire用的是開源的NCrontab組件,跟linux上的crontab指令相似。在本應用中,總頁數在1分鐘之後更新,無法忍受。pass
2.5 Coravel
框架輕,使用簡單,支持秒級定時任務。Coravel Pro可以連接資料庫進行任務調度,Coravel Pro可以支持web可視化,將任務執行情況通過web顯示出來。適合本應用背景。
3 Coravel的一般使用
3.1 Nuget安裝
在調用類庫層安裝Coravel。
3.2 依賴註入
在startup.cs中的ConfigureServices方法中進行依賴註入
services.AddScheduler();
3.3 配置調度器
在startup.cs中的Configure方法中配置鏈兩個定時任務
var provider = app.ApplicationServices;
provider.UseScheduler(scheduler =>
{//配置任務1方法
scheduler.Schedule(() => Console.WriteLine("Every second during the week."))
//工作日每隔1秒輸出
.EverySecond()
.Weekday();
});
provider.UseScheduler(scheduler =>
{//配置任務2方法
scheduler.Schedule(() => Console.WriteLine("Every 5 second during the week."))
//工作日每隔5秒輸出
.EverySeconds(5)
.Weekday();
});
3.4 運行程式,觀察輸出
從上圖結果中可以看到任務1每隔1秒列印輸出;任務2每隔5秒列印輸出,正確。
3.5 Cron 表達式
Coravel 支持Cron Expressions,有需要的可以根據應用場景設置Cron表達式
- * * * * * run every minute
- 00 13 * * * run at 1:00 pm daily
- 00 1,2,3 * * * run at 1:00 pm, 2:00 pm and 3:00 pm daily
- 00 1-3 * * * same as above
- 00 /2 * * run every two hours on the hour
3.6 錯誤支持
Coravel 發佈於2018年6月28日,才剛起步還不成熟,我在調試工作日秒級定時任務的時候會報錯。
詳見#91 https://github.com/jamesmh/coravel/issues/91
作者在幾小時內利用工作時間,解決了問題,還發佈到nuget2.5.1。很是感動。
3.7其他功能支持
此外,Coravel還支持任務隊列,緩存,事件組播,郵件等。任務隊列可依據讀者使用情況,視情況另起一篇,緩存不建議用此組件,可用Easycache。事件組播亦不建議用此庫,可參考 https://www.cnblogs.com/JerryMouseLi/p/11012839.html。 郵件亦不建議用此組件。
3.8 Coravel Pro
Coravel Pro可以連接資料庫進行任務調度,Coravel Pro可以支持web可視化,將任務執行情況通過web顯示出來。在這裡不做詳細介紹,有需要的讀者可自行研究。
4 Coravel的松耦合使用(含總頁數統計)
4.1 依賴註入自定義類
ConfigureServices中對松耦合的類Statistic進行依賴註入
services.AddTransient<Statistic>();
4.2配置調度器
在startup.cs中的Configure方法中配置自定義松耦合任務
var provider = app.ApplicationServices;
provider.UseScheduler(scheduler =>
{
scheduler.Schedule<Statistic>()
.EverySecond()
.Weekday();
});
4.3 編寫松耦合任務的代碼
詳細說明,見代碼註釋。
using Coravel.Invocable;//需要引用此類庫來進行自定義任務
using IBMS.Infrastruct.UoW;
using System;
using System.Threading.Tasks;
namespace IBMS.WEBAPI.Extension
{
public class Statistic: IInvocable
{
//工作單元依賴註入
UnitOfWork _unitOfWork;
public Statistic(UnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public async Task Invoke()
{
//按每頁10分頁計算出來的總頁數
var IPBoxCount = _unitOfWork.IPBoxRepository.Count()/10+1;
Console.WriteLine("Every second during the week.");
Console.WriteLine("Count:{0}", IPBoxCount);
}
}
}
註意:1.編寫的任務一定要在 Invoke中,這屬於固定格式;public async Task Invoke() {};2. 需要引入以下庫:using Coravel.Invocable;
5. 結果驗證
5.1 資料庫有102條數據。按每10條分一頁,總頁數為11頁。
5.2 結果輸出
從結果可以看出,定時計算出總頁數11頁定時1秒輸出。同時可以看到EF Cor ORM最終生成的資料庫語句,與我們的期望相符。
SELECT COUNT(*)
FROM `IPBox` AS `c`
6 小結
當然總頁數的計算可以在每次查詢時生成,如下
var IPBoxCount = _unitOfWork.IPBoxRepository.Count()/10+1;
return Json(new { pageModel, IPBoxCount });
個人覺得,如果數據量小可以直接查詢總數,計算總頁數然後返回的方法;如果數據量很大,比如100萬的數據(狀態,告警,日誌信息等),可能會拖慢速度,使網頁變卡,則使用定時計算總頁數的方法為佳。您覺得呢?不合理的地方可以留言。筆者發現在國內寫Coravel的文章還沒有,如果覺得本文可以,歡迎點右下角推薦,讓Coravel這個優雅的工具被更多人知曉使用。