如何使用Asp.net Core實(shí)現(xiàn)定時(shí)任務(wù),輕松解決任務(wù)調(diào)度問題!
前言
Asp.net core作為一種高效、跨平臺(tái)的web框架,在開發(fā)過程中,我們常常需要在后臺(tái)執(zhí)行定時(shí)任務(wù),例如清理無用文件、生成報(bào)告、發(fā)送郵件等任務(wù)。對于這種需求,我們可以使用第三方庫(如Hangfire或Quartz.NET)來實(shí)現(xiàn)任務(wù)調(diào)度和執(zhí)行,也可以使用asp.net core自帶的Hosting模塊和System.Timers.Timer類來實(shí)現(xiàn)簡單的定時(shí)任務(wù)。
本篇文章主要介紹如何使用Asp.net core自帶的Hosting模塊和System.Timers.Timer類,以及Hangfire和Quartz.NET分別實(shí)現(xiàn)定時(shí)任務(wù)。將展示一個(gè)完整的示例代碼,并詳細(xì)解釋代碼中各個(gè)部分的含義和作用,以幫助理解實(shí)現(xiàn)過程和相關(guān)知識(shí)點(diǎn)。
自帶的Hosting模塊實(shí)現(xiàn)任務(wù)調(diào)度
下面將分步驟詳細(xì)介紹如何使用asp.net core自帶的Hosting模塊和System.Timers.Timer類來實(shí)現(xiàn)定時(shí)任務(wù)。
- 創(chuàng)建一個(gè)控制臺(tái)應(yīng)用程序
首先,在Visual Studio中創(chuàng)建一個(gè)控制臺(tái)應(yīng)用程序。
- 添加必要的NuGet包
在項(xiàng)目中添加以下NuGet包:
- Microsoft.Extensions.Hosting.Abstractions
- Microsoft.Extensions.Hosting
這兩個(gè)NuGet包提供了asp.net core的Hosting模塊和應(yīng)用程序生命周期管理功能。
- 創(chuàng)建一個(gè)HostBuilder對象
在Main方法中創(chuàng)建一個(gè)HostBuilder對象:
static void Main(string[] args)
{
var builder = new HostBuilder()
.UseConsoleLifetime() // 控制臺(tái)生命周期管理
.ConfigureServices((hostContext, services) =>
{
// 配置服務(wù)
});
builder.Build().Run();
}
HostBuilder提供了配置應(yīng)用程序服務(wù)、托管生命周期、配置應(yīng)用程序配置等功能。可以使用UseConsoleLifetime方法來配置應(yīng)用程序的控制臺(tái)生命周期管理。
- 添加定時(shí)任務(wù)
在ConfigureServices方法中添加定時(shí)任務(wù):
ConfigureServices((hostContext, services) =>
{
// 添加定時(shí)器組件
services.AddHostedService<MyTimer>();
});
上面的代碼中,我們向服務(wù)容器中添加了一個(gè)MyTimer類,這個(gè)類實(shí)現(xiàn)了IHostedService接口。
- 實(shí)現(xiàn)IHostedService接口
在MyTimer類中實(shí)現(xiàn)IHostedService接口:
// MyTimer.cs
public class MyTimer : IHostedService, IDisposable
{
private readonly Timer _timer;
public MyTimer()
{
_timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(5)); // 每5秒執(zhí)行一次DoWork方法
}
public Task StartAsync(CancellationToken cancellationToken)
{
Console.WriteLine("定時(shí)任務(wù)已啟動(dòng)");
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
Console.WriteLine("定時(shí)任務(wù)已停止");
return Task.CompletedTask;
}
public void Dispose()
{
_timer?.Dispose();
}
private void DoWork(object state)
{
Console.WriteLine($"定時(shí)任務(wù)執(zhí)行中,當(dāng)前時(shí)間:{DateTime.Now}");
}
}
MyTimer類繼承了IHostedService接口,該接口定義了應(yīng)用程序生命周期管理的方法。在MyTimer的構(gòu)造函數(shù)中,我們創(chuàng)建了一個(gè)計(jì)時(shí)器,并在每5秒鐘的時(shí)間間隔內(nèi)執(zhí)行DoWork方法。在StartAsync方法中,輸出“定時(shí)任務(wù)已啟動(dòng)”信息;在StopAsync方法中,輸出“定時(shí)任務(wù)已停止”信息。Dispose方法用于釋放計(jì)時(shí)器資源。
- 運(yùn)行應(yīng)用程序
完成上面的步驟后,我們可以運(yùn)行應(yīng)用程序,觀察控制臺(tái)輸出的結(jié)果。
每5秒鐘控制臺(tái)會(huì)輸出一條類似于“定時(shí)任務(wù)執(zhí)行中,當(dāng)前時(shí)間:2023/06/12 15:34:48”的信息,表示定時(shí)任務(wù)正在運(yùn)行。當(dāng)我們手動(dòng)停止應(yīng)用程序時(shí),控制臺(tái)會(huì)輸出“定時(shí)任務(wù)已停止”信息,表示定時(shí)任務(wù)已經(jīng)被成功停止。
至此,我們成功地使用asp.net core自帶的Hosting模塊和System.Timers.Timer類實(shí)現(xiàn)了定時(shí)任務(wù)。在實(shí)際應(yīng)用中,可以根據(jù)需求添加更多的定時(shí)任務(wù),并調(diào)整計(jì)時(shí)器的時(shí)間間隔等參數(shù)。
Hangfire實(shí)現(xiàn)任務(wù)調(diào)度
下面將詳細(xì)介紹如何使用asp.net core引入Hangfire來實(shí)現(xiàn)任務(wù)調(diào)度和執(zhí)行。
- 創(chuàng)建一個(gè)asp.net core Web應(yīng)用程序
首先,在Visual Studio中創(chuàng)建一個(gè)asp.net core Web項(xiàng)目。
- 添加必要的NuGet包
在項(xiàng)目中添加以下NuGet包:
- Hangfire.AspNetCore
- Hangfire.SqlServer
這兩個(gè)NuGet包提供了Hangfire框架所需的組件和功能。
- 配置Hangfire
在Startup.cs文件中配置Hangfire:
public void ConfigureServices(IServiceCollection services)
{
// 配置Hangfire
GlobalConfiguration.Configuration.UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection"));
services.AddHangfire(config => config.UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection")));
services.AddHangfireServer();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// 啟用Hangfire儀表板
app.UseHangfireDashboard();
// ...
}
上述代碼中,我們在ConfigureServices方法中配置了Hangfire,并使用AddHangfireServer方法啟用了Hangfire服務(wù)。同時(shí),我們也針對數(shù)據(jù)庫進(jìn)行了配置。
在Configure方法中,我們除了啟用了Hangfire儀表板之外,還需要在中間件管道中注冊Hangfire服務(wù):
app.UseHangfireServer();
- 添加定時(shí)任務(wù)
在Actions文件夾內(nèi)創(chuàng)建ScheduledTasks類,并添加定時(shí)任務(wù):
public class ScheduledTasks
{
public void DoSomething()
{
Console.WriteLine("Hangfire: Doing something...");
}
public void DoSomethingElse()
{
Console.WriteLine("Hangfire: Doing something else...");
}
}
在上面的代碼中,我們創(chuàng)建了兩個(gè)定時(shí)任務(wù):DoSomething和DoSomethingElse。
- 注冊定時(shí)任務(wù)
在ConfigureServices方法中注冊定時(shí)任務(wù):
services.AddTransient<ScheduledTasks>();
// 注冊定時(shí)任務(wù)
RecurringJob.AddOrUpdate<ScheduledTasks>(x => x.DoSomething(), Cron.Minutely);
RecurringJob.AddOrUpdate<ScheduledTasks>(x => x.DoSomethingElse(), Cron.Hourly);
在上面的代碼中,我們使用AddOrUpdate方法來注冊定時(shí)任務(wù)。第一個(gè)參數(shù)為委托表達(dá)式,指定了要執(zhí)行的任務(wù);第二個(gè)參數(shù)為Cron表達(dá)式,指定了任務(wù)的執(zhí)行時(shí)間。
在上面的代碼中,我們每分鐘執(zhí)行DoSomething任務(wù),每小時(shí)執(zhí)行DoSomethingElse任務(wù)。
- 運(yùn)行應(yīng)用程序
完成上面的步驟后,我們可以運(yùn)行應(yīng)用程序在Hangfire儀表板中查看定時(shí)任務(wù)的執(zhí)行情況。
在儀表板的"Recurring jobs"選項(xiàng)卡中,我們可以看到我們剛剛注冊的兩個(gè)定時(shí)任務(wù)以及它們的下一次執(zhí)行時(shí)間。在任務(wù)執(zhí)行時(shí),我們可以在控制臺(tái)輸出中看到“Hangfire: Doing something…”或“Hangfire: Doing something else…”等信息,表示任務(wù)已經(jīng)被成功執(zhí)行。
至此,我們成功地使用asp.net core引入Hangfire來實(shí)現(xiàn)任務(wù)調(diào)度和執(zhí)行,并注冊了兩個(gè)定時(shí)任務(wù)進(jìn)行演示。在實(shí)際應(yīng)用中,我們可以根據(jù)需求添加更多的定時(shí)任務(wù),并根據(jù)具體業(yè)務(wù)場景進(jìn)行調(diào)整和優(yōu)化。