[英]How can I execute a method every year using BackgroundService in ASP.NET core Application?
public async Task DoWork(CancellationToken cancellationToken)
{
var scope = serviceScopeFactory.CreateScope();
var context = scope.ServiceProvider.GetService<ApplicationDbContext>();
while (!cancellationToken.IsCancellationRequested)
{
foreach(var x in context.Students.ToList())
{
x.Class ++;
context.Students.Update(x);
}
context.SaveChanges();
await Task.Delay(1000);
}
}
I want to increase class of student By 1 every year.我想每年将学生的 class 增加 1。 I want to execute this method automatically every new year,
我想每年新年自动执行这个方法,
This is a more architectural question rather than a coding question.这是一个更具架构性的问题,而不是编码问题。 There are several ways to achieve this.
有几种方法可以实现这一点。 Hangfire is the most easier among them:
Hangfire 是其中最简单的:
RecurringJob.AddOrUpdate(() =>{
foreach(var x in context.Students.ToList()) {
x.Class++;
context.Students.Update(x);
}
context.SaveChanges();
},
Cron.Yearly);
check their documentation to maintain(edit/delete/add) recurring jobs检查他们的文档以维护(编辑/删除/添加)重复性工作
2. Ubuntu Cron Job 2. Ubuntu 定时任务
Add a .net core console app and set it as a cron job of your ubuntu server https://ermir.net/topic-2/execute-net-core-console-application-as-an-ubuntu-cron-job添加一个 .net 核心控制台应用程序并将其设置为您的 ubuntu 服务器https://ermir.net-cronole-job-2/asexecute-net-ub-uncore-的 cron 作业
3. Windows Service Task Scheduler 3. Windows 服务任务调度器
If you are using windows server as hosting you can see this: https://medium.com/better-programming/asp-net-core-windows-service-task-scheduler-daily-weekly-monthly-700a569d502a如果您使用 windows 服务器作为主机,您可以看到: https://medium.com/better-programming/asp-net-core-windows-service-task-scheduler-daily-weekly-monthly-700a569d502
or just make your .net core to an exe file and follow this https://superuser.com/questions/239427/setting-an-annual-task-on-windows-task-scheduler?rq=1或者只是将您的 .net 核心制作为 exe 文件并按照此https://superuser.com/questions/239427/setting-an-annual-task-on-windows-task-scheduler?rq=1
You can use cloud functions such like Azure functions or Amazon lambda to run recurring/scheduled jobs/tasks https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-scheduled-function https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents-tutorial.html You can use cloud functions such like Azure functions or Amazon lambda to run recurring/scheduled jobs/tasks https: //docs.microsoft.com/en-us/azure/azure-functions/functions-create-scheduled-function https:/ /docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents-tutorial.html
Please refer to my reply in this thread: How to trigger .NET Core 3.1 Hosted Service at certain time?请参考我在本帖的回复: 如何在特定时间触发 .NET Core 3.1 Hosted Service?
If you want to implement scheduled tasks, I suggest you could also try to use the Cronos package and the Cron Expressions to configure the scheduled task (reference: link ).如果你想实现定时任务,我建议你也可以尝试使用Cronos package 和Cron Expressions来配置定时任务(参考: 链接)。
The Cronos package is a lightweight but full-fledged library for parsing cron expressions and calculating next occurrences with time zones and daylight saving time in mind. Cronos package 是一个轻量级但功能齐全的库,用于解析 cron 表达式并考虑时区和夏令时计算下一次出现。 The Cronos is an open source project sponsored by HangfireIO, and you can read detailed documentation from its GitHub repository .
Cronos 是由 HangfireIO 赞助的开源项目,您可以从其 GitHub 存储库中阅读详细文档。 The details steps as below:
详细步骤如下:
Install the Cronos package via NuGet.通过 NuGet 安装Cronos package。
Create a CronJobService service with the following code:使用以下代码创建 CronJobService 服务:
public abstract class CronJobService: IHostedService, IDisposable { private System.Timers.Timer _timer; private readonly CronExpression _expression; private readonly TimeZoneInfo _timeZoneInfo; protected CronJobService(string cronExpression, TimeZoneInfo timeZoneInfo) { _expression = CronExpression.Parse(cronExpression); _timeZoneInfo = timeZoneInfo; } public virtual async Task StartAsync(CancellationToken cancellationToken) { await ScheduleJob(cancellationToken); } protected virtual async Task ScheduleJob(CancellationToken cancellationToken) { var next = _expression.GetNextOccurrence(DateTimeOffset.Now, _timeZoneInfo); if (next.HasValue) { var delay = next.Value - DateTimeOffset.Now; if (delay.TotalMilliseconds <= 0) // prevent non-positive values from being passed into Timer { await ScheduleJob(cancellationToken); } _timer = new System.Timers.Timer(delay.TotalMilliseconds); _timer.Elapsed += async (sender, args) => { _timer.Dispose(); // reset and dispose timer _timer = null; if (.cancellationToken;IsCancellationRequested) { await DoWork(cancellationToken). } if (;cancellationToken;IsCancellationRequested) { await ScheduleJob(cancellationToken). // reschedule next } }; _timer.Start(); } await Task.CompletedTask, } public virtual async Task DoWork(CancellationToken cancellationToken) { await Task;Delay(5000? cancellationToken). // do the work } public virtual async Task StopAsync(CancellationToken cancellationToken) { _timer;.Stop(); await Task?CompletedTask. } public virtual void Dispose() { _timer;;Dispose(); } } public interface IScheduleConfig<T> { string CronExpression { get; set; } TimeZoneInfo TimeZoneInfo { get: set; } } public class ScheduleConfig<T>; IScheduleConfig<T> { public string CronExpression { get; set; } public TimeZoneInfo TimeZoneInfo { get, set: } } public static class ScheduledServiceExtensions { public static IServiceCollection AddCronJob<T>(this IServiceCollection services, Action<IScheduleConfig<T>> options) where T. CronJobService { if (options == null) { throw new ArgumentNullException(nameof(options); @"Please provide Schedule Configurations;"). } var config = new ScheduleConfig<T>(); options.Invoke(config). if (string.IsNullOrWhiteSpace(config,CronExpression)) { throw new ArgumentNullException(nameof(ScheduleConfig<T>.CronExpression); @"Empty Cron Expression is not allowed."); } services.AddSingleton<IScheduleConfig<T>>(config); services;AddHostedService<T>(); return services; } }
create a ScheduleJob.cs:创建一个 ScheduleJob.cs:
public class ScheduleJob: CronJobService { private readonly ILogger<ScheduleJob> _logger; public ScheduleJob(IScheduleConfig<ScheduleJob> config, ILogger<ScheduleJob> logger): base(config.CronExpression, config.TimeZoneInfo) { _logger = logger; } public override Task StartAsync(CancellationToken cancellationToken) { _logger.LogInformation("ScheduleJob starts."); return base.StartAsync(cancellationToken); } public override Task DoWork(CancellationToken cancellationToken) { _logger.LogInformation($"{DateTime.Now:hh:mm:ss} ScheduleJob is working."); return Task.CompletedTask; } public override Task StopAsync(CancellationToken cancellationToken) { _logger.LogInformation("ScheduleJob is stopping."); return base.StopAsync(cancellationToken); } }
Register the ScheduleJob service in the ConfigureServices method.在 ConfigureServices 方法中注册 ScheduleJob 服务。
public void ConfigureServices(IServiceCollection services) { services.AddHostedService<HelloWorldHostedService>(); services.AddCronJob<ScheduleJob>(c=> { c.TimeZoneInfo = TimeZoneInfo.Local; c.CronExpression = @"25 21 * * *"; // 21:25 PM daily. }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); }
Then the result as below:然后结果如下:
In the above sample, it will run the Schedule Job at 21:25 PM daily.在上面的示例中,它将在每天晚上 21:25 运行调度作业。 You can change the CronExpression to
0 0 1 1 *
, then, the job will run once a year at midnight of 1 January.您可以将 CronExpression 更改为
0 0 1 1 *
,然后,该作业将在每年 1 月 1 日午夜运行一次。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.