0%

[DotnetCore]排程利器-Coravel:Scheduler篇

前情提要

筆者因工作有需求要實作排程,以傳統做法來說,最簡單的方式是撰寫一支獨立的console或其他可以產生執行檔的專案,由Windows排程去設定,於某一個特定時間執行某一個自己撰寫的程式執行檔案,但是壞處是我得獨立一個專案,如果以簡易的排程來說太麻煩,本身有API站台要發佈,排程若有更新則需要再發佈一個排程的執行擋。

筆者期初的想法是能找到一個套件依附於API站台專案中,因筆者針對測試環境,有設定WebDeploy的功能,因此很容易發佈更新版本,不需要手動發佈執行檔檔案並調整Windows排程。筆者有在關注ASP.NET CORE Developer Roadmap,不時會在上面找好料,Coravel本身也是從其中的TaskScheduling區塊中找到,就試著用用看吧

內容

Coravel本身支援諸多應用,免費版的SchedulerQueue等等功能,至於Dashboard功能付費版才有,筆者這篇以Scheduler為主介紹其應用方式。

簡單應用

首先建立WebAPI專案

1
dotnet new webapi --output Coravel.API

請使用Visual Studio Code開啟專案

安裝Coravel套件

1
dotnet add package coravel

請於Startup.cs中撰寫程式

1
2
3
4
5
6
7
8
services.AddScheduler();

var provider = app.ApplicationServices;
provider.UseScheduler(scheduler => {
scheduler.Schedule(() => {
System.Console.WriteLine($"Hello World! {DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}");
}).EveryMinute();
});

完整程式碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
// 以上省略
services.AddScheduler();
// 以下省略
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 以上省略
app.ApplicationServices.UseScheduler(scheduler => {
scheduler.Schedule(() => {
System.Console.WriteLine($"Hello World! {DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}");
}).EveryMinute();
});
// 以下省略
}
}

執行結果參考

進階應用

執行一個Service

首先建立一個Class,筆者命名為「SchedulerService.cs」,需要實作「IInvocable

1
2
3
4
5
6
7
8
9
10
11
12
public class SchedulerService : IInvocable {
private readonly IHostEnvironment _env;
private readonly IConfiguration _config;
public SchedulerService(IHostEnvironment env, IConfiguration config) {
_env = env;
_config = config;
}
public Task Invoke() {
System.Console.WriteLine($"[SchedulerService {DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss")}]: {_env.ContentRootPath}");
return Task.CompletedTask;
}
}

接下來,要來改寫Startup.cs中的程式

1
2
3
4
5
6
7
8
9
// 注入Service
services.AddTransient<SchedulerService>();

// Schedule改執行自己撰寫的Service
var provider = app.ApplicationServices;
provider.UseScheduler(scheduler => {
scheduler.Schedule<SchedulerService>()
.EverySecond();// 改為每秒執行
});

執行效果如下

由執行結果可以發現,我們使用自己撰寫的Service是支援dotnet core的DI機制運作,亦即.net core可以使用的注入服務皆可使用,換言之,你也可以注DbContext,於Scheduler Service使用Entity Framework Core與資料庫連線並操作的。

其中要特別注意,上述有提到Coravel本身有支援dotnet core的DI機制運作,因此本身自己的Service記得也要注入,不然會爆錯。

Worker Service中應用

使用Visual Studiodotnet command的方式新增 Worker Service專案

1
dotnet new worker -n {ProjectName}

接著找到program.cs中設置Scheduler資訊,完整程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Program
{
public static void Main(string[] args)
{
// 原本是CreateHostBuilder(args).Build().Run();
IHost host = CreateHostBuilder(args).Build();
host.Services.UseScheduler(scheduler =>
{
scheduler.Schedule<SchedulerService>()
.EveryFiveMinutes();
});
host.Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddScheduler();
services.AddHostedService<Worker>();
});
}

結論

以簡易的排程來說,Coravel本身以足夠應用,算是短小精幹型的套件,其設定方式也是簡單,且也適用dotnet core的DI機制,筆者就覺得很棒了,下篇再來寫它的Queue功能。