.NET 8 强大功能 IHostedService 与 BackgroundService 实战
简介:
【11月更文挑战第7天】本文介绍了 ASP.NET Core 中的 `IHostedService` 和 `BackgroundService` 接口及其用途。`IHostedService` 定义了 `StartAsync` 和 `StopAsync` 方法,用于在应用启动和停止时执行异步操作,适用于资源初始化和清理等任务。`BackgroundService` 是 `IHostedService` 的抽象实现,简化了后台任务的编写,通过 `ExecuteAsync` 方法实现长时间运行的任务逻辑。文章还提供了创建和注册这两个服务的实战步骤,帮助开发者在实际项目中应用这些功能。
一、IHostedService 和 BackgroundService 概述
1. IHostedService
- 定义:
IHostedService
是一个接口,它定义了两个方法StartAsync
和StopAsync
,用于在应用程序启动和停止时执行一些异步操作。这使得开发者可以方便地将长时间运行的任务集成到ASP.NET Core 应用程序的生命周期中。例如,你可能想要在应用启动时初始化一些资源,或者在应用关闭时清理资源。
- 用途示例:
- 可以用于启动一个定时器,定时从数据库中获取数据更新缓存。
- 连接到消息队列,开始消费消息,并且在应用关闭时正确地断开连接。
2. BackgroundService
- 定义:
BackgroundService
是一个抽象类,它实现了IHostedService
接口。它提供了一个更方便的基类来创建后台服务。你只需要重写ExecuteAsync
方法,在这个方法中编写需要在后台长时间运行的任务逻辑。
- 与 IHostedService 的关系:
BackgroundService
简化了IHostedService
的使用。它自动处理了一些基本的启动和停止逻辑,并且通过CancellationToken
提供了一种优雅的方式来停止正在运行的后台任务。
二、实战步骤
1. 创建一个简单的 IHostedService 示例
- 首先,创建一个新的ASP.NET Core 项目。可以通过命令行(
dotnet new webapi -n MyHostedServiceApp
)或者使用 Visual Studio 等集成开发环境来创建。
- 创建一个类,例如
MyHostedService
,并让它实现IHostedService
接口。
using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Threading.Tasks;
public class MyHostedService : IHostedService
{
private readonly ILogger<MyHostedService> _logger;
private Timer _timer;
public MyHostedService(ILogger<MyHostedService> logger)
{
_logger = logger;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("MyHostedService is starting.");
_timer = new Timer(DoWork, null, TimeSpan.Zero,
TimeSpan.FromSeconds(5));
return Task.CompletedTask;
}
private void DoWork(object state)
{
_logger.LogInformation("MyHostedService is doing work.");
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("MyHostedService is stopping.");
_timer?.Dispose();
return Task.CompletedTask;
}
}
- 在
StartAsync
方法中,创建了一个定时器Timer
,它会每隔 5 秒调用一次DoWork
方法。DoWork
方法在这里只是简单地记录一条日志信息。在StopAsync
方法中,正确地释放了定时器资源。
- 步骤三:注册服务
- 在
Program.cs
文件中,将MyHostedService
注册到服务容器中。
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
services.AddHostedService<MyHostedService>();
});
var host = builder.Build();
await host.RunAsync();
- 当应用启动时,
MyHostedService
的StartAsync
方法会被调用,定时器开始工作;当应用关闭时,StopAsync
方法会被调用来清理资源。
2. 创建一个 BackgroundService 示例
- 步骤一:创建类并继承 BackgroundService
- 创建一个名为
MyBackgroundService
的类,继承自BackgroundService
。
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System.Threading;
using System.Threading.Tasks;
public class MyBackgroundService : BackgroundService
{
private readonly ILogger<MyBackgroundService> _logger;
public MyBackgroundService(ILogger<MyBackgroundService> logger)
{
_logger = logger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("MyBackgroundService is working.");
await Task.Delay(3000, stoppingToken);
}
}
}
- 在
ExecuteAsync
方法中,通过一个while
循环来实现长时间运行的任务。只要stoppingToken
没有被请求取消,就会每隔 3 秒记录一条日志信息。Task.Delay
方法在这里也接受stoppingToken
,这意味着当服务需要停止时,Delay
操作也会被正确地取消。
- 步骤二:注册服务
- 同样在
Program.cs
文件中,将MyBackgroundService
注册到服务容器中。
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
var builder = Host.CreateDefaultBuilder(args)
.ConfigureServices((context, services) =>
{
services.AddHostedService<MyBackgroundService>();
});
var host = builder.Build();
await host.RunAsync();
- 这样,
MyBackgroundService
就会在应用启动时开始运行,并且在应用关闭时能够正确地停止。
三、总结
- 通过
IHostedService
和BackgroundService
可以方便地在ASP.NET Core 应用中实现后台任务。IHostedService
提供了基本的应用生命周期集成,而BackgroundService
则进一步简化了编写长时间运行任务的过程。在实际应用中,可以根据具体需求选择使用哪种方式,例如对于简单的定时任务或者资源初始化 / 清理任务,IHostedService
可能就足够了;而对于更复杂的、需要持续运行并能够正确响应停止请求的后台任务,BackgroundService
是更好的选择。同时,要注意在注册服务时,确保服务能够正确地被注入到容器中,并且在应用生命周期的各个阶段都能按照预期工作。