.Net Core之后台任务
作者:互联网
.Net Core之后台任务
.Net Core自带的后台任务可以满足基础需求,而更高级的用法则需要自己实现或使用第三方库,比如Hangfire
自带后台任务(IHostedService)
一次性,周期性,任务队列都可以通过IHostedService快速实现,微软官方文档已经做了很详细的说明,我这里就放出一个周期任务的例子
/// <summary>
/// 定时任务
/// </summary>
public class TimedHostedService : IHostedService, IDisposable
{
private int executionCount = 0;
private readonly ILogger<TimedHostedService> _logger;
private Timer _timer;
public TimedHostedService(ILogger<TimedHostedService> logger)
{
_logger = logger;
}
public Task StartAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Timed Hosted Service running.");
//周期:一小时
_timer = new Timer(DoWork, null, TimeSpan.Zero,
TimeSpan.FromHours(1));
return Task.CompletedTask;
}
private void DoWork(object state)
{
var count = Interlocked.Increment(ref executionCount);
//逻辑代码
_logger.LogInformation(
"Timed Hosted Service is working. Count: {Count}", count);
}
public Task StopAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Timed Hosted Service is stopping.");
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose()
{
_timer?.Dispose();
}
}
折叠
Hangfire
Hangfire在很多方面都做得很好,比起Quartz.NET,有web管理页面,集成和管理更方便,这里也不对两者进行比较
-
集成
这里使用SqlServer做持久化
//ConfigureServices里注入
services.AddHangfire(configuration => configuration
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings()
.UseSqlServerStorage(connectionString, new SqlServerStorageOptions
{
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true,
UsePageLocksOnDequeue = true,
DisableGlobalLocks = true
}));
//Configure里启用
//Hangfire管理页面
app.UseHangfireDashboard("/hangfire", new DashboardOptions()
{
Authorization = new[] { new HangFireAuthorizationFilter() }
});
app.UseHangfireServer();
-
任务定义
使用Hangfire定义后台任务是完全解耦的,只需要把对应的任务方法提供出来即可,这里注入IServiceProvider,方便复杂任务的处理
/// <summary>
/// 定时任务
/// </summary>
public class JobService
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger _logger;
public JobService(IServiceProvider serviceProvider, ILogger<JobService> logger)
{
_serviceProvider = serviceProvider;
_logger = logger;
}
public async Task DoWork()
{
_logger.LogInformation($"Start DoWork");
using (var scope = _serviceProvider.CreateScope())
{
//逻辑代码
}
_logger.LogInformation($"End DoWork");
}
}
services.AddSingleton<JobService>();
-
任务使用
使用Hangfire触发后台任务很简单,只需要在使用的地方触发就可以
//后台任务:立刻执行
BackgroundJob.Enqueue(() => _jobService.DoWork());
//计划任务:1分钟后执行
BackgroundJob.Schedule(() => _jobService.DoWork(), TimeSpan.FromMinutes(1));
//周期任务:每小时执行一次
RecurringJob.AddOrUpdate(id, () => _jobService.DoWork(), Cron.Hourly);
//可以通过任务id取消任务
RecurringJob.RemoveIfExists(id);
-
任务管理
Hangfire提供了web管理页面,可以查看,操作任务,同样提供了接口来自己查询任务数据。
我们也可以自己获取数据,定制自己的web管理页面,这里以周期任务为例,做一些基础查询
public JobInfo GetJobInfo(string id) { //通过任务id获取信息 var connection = JobStorage.Current.GetConnection(); var jobData = connection.GetAllEntriesFromHash($"recurring-job:{id}"); if (!jobData.IsNullOrEmpty()) { result.Running = true; if (jobData.TryGetValue("Cron", out var cron)) { result.Cron = cron; } if (jobData.TryGetValue("NextExecution", out var nextExecution)) { result.NextExecution = DateTimeOffset.FromUnixTimeMilliseconds(long.Parse(nextExecution)) .LocalDateTime; } if (jobData.TryGetValue("LastExecution", out var lastExecution)) { result.LastExecution = DateTimeOffset.FromUnixTimeMilliseconds(long.Parse(lastExecution)) .LocalDateTime; } } return result; }
标签:Core,Net,DoWork,Hangfire,public,任务,后台任务,logger 来源: https://www.cnblogs.com/wl-blog/p/16425649.html