PeriodicTimer 和 BackgroundService

发布时间 2023-04-09 23:11:44作者: HackerVirus

实现 .Net 7 下的数据库定时检查

 

在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在 .Net 7 下进行一次简单的演示。

PeriodicTimer

.Net 6 中新增了 PeriodicTimer 这个类,它可以用来创建一个定时器,以固定间隔的时间调用回调函数。使用方法如下:

  using var timer = new PeriodicTimer(TimeSpan.FromSeconds(10));
  while (await timer.WaitForNextTickAsync())
  {
      //Business logic
  }

这样就可以每隔 10 秒执行一次操作。

PeriodicTimer 相比于传统 Timer 的优势在于:

  • PeriodicTimer 将使我们能够异步地等待指定的时间间隔。
  • 在回调的执行过程中,我们可以阻止下一次回调的执行,直到我们完成了当前的操作。

BackgroundService

AspNetCore 中的 BackgroundService 类,它是一个抽象类,实现了 IHostService 接口,可以被用来创建后台服务。使用方法如下:

  using System;
  using System.Threading;
  using System.Threading.Tasks;
  using Microsoft.Extensions.Hosting;
   
  namespace ConsoleApp1
  {
      public class DatabaseCheckService : BackgroundService
      {
          protected override async Task ExecuteAsync(CancellationToken stoppingToken)
          {
              while (!stoppingToken.IsCancellationRequested)
              {
                  Console.WriteLine("Checking database...");
                  // 检查数据库代码
                  await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
              }
          }
      }
   
      class Program
      {
          static void Main(string[] args)
          {
              var host = new HostBuilder()
                  .ConfigureServices((hostContext, services) =>
                  {
                      services.AddHostedService<DatabaseCheckService>();
                  })
                  .Build();
   
              host.Run();
          }
      }
  }

在这个例子中,我们继承了 BackgroundService 类并重写了 ExecuteAsync 方法。ExecuteAsync 方法会在后台服务启动时被调用,并在参数 stoppingToken 被取消时退出。我们在 while 循环中使用 Task.Delay 方法来等待 5 秒,并在每次循环中调用检查数据库的代码。

结合使用

我们可以将 PeriodicTimer 和 BackgroundService 结合起来,实现一个定时检查数据库的后台服务。代码如下:

  using System;
  using System.Threading;
  using System.Threading.Tasks;
  using Microsoft.Extensions.Hosting;
  using Microsoft.Extensions.Logging;
   
  namespace ConsoleApp1
  {
      public class DatabaseCheckService : BackgroundService
      {
          protected override async Task ExecuteAsync(CancellationToken stoppingToken)
          {
              using var timer = new PeriodicTimer(TimeSpan.FromSeconds(10));
              while (!stoppingToken.IsCancellationRequested)
              {
                  if (await timer.WaitForNextTickAsync(stoppingToken))
                  {
                      Console.WriteLine("Checking database...");
                      // 检查数据库代码
                  }
              }
          }
      }
   
      class Program
      {
          static void Main(string[] args)
          {
              var host = new HostBuilder()
                  .ConfigureServices((hostContext, services) =>
                  {
                      services.AddHostedService<DatabaseCheckService>();
                  })
                  .Build();
   
              host.Run();
          }
      }
  }

总结

在这篇文章中,我们介绍了如何使用 .Net 7 中的 PeriodicTimer 类和 BackgroundService 类来实现一个定时检查数据库的后台服务。实际使用中会遇到更多复杂的场景,这篇文章只是一个简单的示例。

参考链接

  • PeriodicTimer[1]
  • Hosted Services in ASP.NET Core[2]

本文采用 Chat OpenAI 辅助注水浇筑而成,如有雷同,完全有可能。

  • 本文作者: newbe36524
  • 本文链接: https://www.newbe.pro/ChatAI/How-to-create-a-timer-host-service/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

参考资料

[1]

PeriodicTimer: https://learn.microsoft.com/dotnet/api/system.threading.periodictimer?view=net-7.0&WT.mc_id=DX-MVP-5003606

[2]

Hosted Services in ASP.NET Core: https://learn.microsoft.com/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-6.0&WT.mc_id=DX-MVP-5003606