简体   繁体   English

如何在 ASP.NET 核心应用程序中使用 BackgroundService 每年执行一个方法?

[英]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 是其中最简单的:

1. Hangfire 1.挂火

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

  1. Cloud hosted functions云托管功能

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:详细步骤如下:

  1. Install the Cronos package via NuGet.通过 NuGet 安装Cronos package。

  2. 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; } }
  3. 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); } }
  4. 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.

相关问题 .NET 5 WindowsService with ASP.NET Core and BackgroundService - .NET 5 WindowsService with ASP.NET Core and BackgroundService 如何在 ASP.net 内核中手动取消 BackgroundService - How to cancel manually a BackgroundService in ASP.net core 如何在 ASP.NET Core 2.1 中的计时器上运行 BackgroundService - How to run BackgroundService on a timer in ASP.NET Core 2.1 如何手动重启 ASP.net 核心中的 BackgroundService - How to restart manually a BackgroundService in ASP.net core ASP.Net core 3.1中如何启动BackgroundService API - How to start BackgroundService in ASP.Net core 3.1 API 我可以在 dot net core 控制台应用程序中使用 BackgroundService - Can I use BackgroundService in dot net core console application 如何使用 EF Core 3.1.5 解决 ASP.net Core 应用程序中的 null 引用异常? - How can I resolve null reference exception in ASP.net Core application using EF Core 3.1.5? 如何每24小时在Asp.net MVC中执行一个方法 - How to execute a method in Asp.net MVC for every 24 hours 使用 ASP.NET 核心 6 最小 ZDB93474238D104CAADE1 停止 Azure 中的 Web 应用程序时未调用 BackgroundService StopAsync - BackgroundService StopAsync not called when stopping Web App in Azure using ASP.NET Core 6 Minimal API 从asp.net core 2.1中的控制器访问BackgroundService - access BackgroundService from controller in asp.net core 2.1
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM