一 应用场景对比
维度 | IHostedService | BackgroundService |
---|---|---|
任务类型 | 短周期、简单任务(如定时日志、单次数据检查) | 长周期、持续运行任务(如消息队列监听、数据同步) |
实现复杂度 | 需手动管理线程、取消逻辑,代码量较多 | 封装了生命周期管理,专注业务逻辑,代码更简洁 |
异常处理 | 需自行处理异常和重启逻辑 | 内置基本异常处理,可重写 StopAsync 增强可靠性 |
适用于 | 轻量级工具、一次性操作、简单定时任务 | 微服务后台服务、长期运行的守护进程、高可靠性场景 |
典型案例 | 定时清理临时文件、周期性健康检查 | 实时消息推送、文件监控服务、后台数据处理引擎 |
二、如何选择?
-
优先使用 BackgroundService:
- 当任务需要持续运行(如循环处理数据)或需要简化生命周期管理时。
- 希望减少代码量,专注业务逻辑而非底层线程控制。
-
使用 IHostedService:
- 任务逻辑非常简单(如单次启动时的初始化操作)。
- 需要完全自定义服务的启动 / 停止逻辑(如复杂的多线程协调)。
三、说人话 上代码
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using SocketClientServer.Services.Interface;
namespace SocketClientServer.Services
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly ISocketClientService _socketClientService;
public Worker(
ILogger<Worker> logger,
ISocketClientService socketClientService)
{
_logger = logger;
_socketClientService = socketClientService;
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
await _socketClientService.DisconnectAllAsync(cancellationToken); // 释放定时器资源
await base.StopAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Worker starting at: {time}", DateTimeOffset.Now);
try
{
// 保持服务运行
while (!stoppingToken.IsCancellationRequested)
{
await _socketClientService.ConnectAllAsync(stoppingToken);
//间隔5钟发送一次消息
await Task.Delay(5000, stoppingToken);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "服务执行过程中发生错误");
}
finally
{
// 停止心跳检测
//_socketClientService.StopHeartbeat();
// 断开所有连接
await _socketClientService.DisconnectAllAsync(stoppingToken);
_logger.LogInformation("服务已停止,所有连接已断开");
}
}
}
}
BackgroundService 实现了 IHostedService 接口并且无需手动管理线程周期省事还考虑啥 直接用这个就完了。
依赖注入
// 添加主机服务
services.AddHostedService<Worker>();
注册实现了 IHostedService
接口的后台服务类,使其随应用启动自动运行,当然你有多个也可以实现多个服务类 注册多个就可以了