You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Worker Service监听端点触发事件并执行指定方法

Worker Service 监听事件实现方案

需求:已通过端点触发事件,需实现Worker Service监听该事件,事件触发时执行对应方法。

当前代码实现

public class WorkerService : BackgroundService
{
    private readonly ILogger<WorkerService> _logger;
    private readonly IEventService _eventService;

    public WorkerService(ILogger<WorkerService> logger, IEventService eventService)
    {
        _logger = logger;
        _eventService = eventService;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _eventService.RegEvent += Log;
         await Task.Delay(2000);
        _eventService.RegEvent -= Log;

    }

    private void Log(string message)
    {
        _logger.LogInformation("dssd");
    }
}

public interface IEventService
{
    public delegate void RegistrationEvent(string message);

    public event RegistrationEvent RegEvent;
    public void InvokeEvent();

}

public class EventService : IEventService
{
    private readonly ILogger<EventService> _logger;

    public event IEventService.RegistrationEvent RegEvent;

    public EventService(ILogger<EventService> logger)
    {
        _logger = logger;
    }

    public void InvokeEvent()
    {
        RegEvent?.Invoke("Test message");
        _logger.LogInformation($"From {nameof(EventService)}");
    }
}

问题分析

当前代码存在两个核心问题:

  1. 监听生命周期过短:ExecuteAsync中订阅事件后仅延迟2秒就取消订阅,Worker Service启动后很快就不再监听事件,无法满足持续监听的需求;
  2. 未利用事件参数:Log方法硬编码固定字符串,未使用事件传递的message参数。

修正后的实现

1. 调整Worker Service的监听逻辑

确保Worker Service在运行期间始终订阅事件,直到服务停止时才取消订阅:

public class WorkerService : BackgroundService
{
    private readonly ILogger<WorkerService> _logger;
    private readonly IEventService _eventService;

    public WorkerService(ILogger<WorkerService> logger, IEventService eventService)
    {
        _logger = logger;
        _eventService = eventService;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        // 启动时订阅事件
        _eventService.RegEvent += Log;
        _logger.LogInformation("Worker Service 已订阅事件");

        try
        {
            // 等待服务停止信号,保持服务运行
            await Task.Delay(Timeout.Infinite, stoppingToken);
        }
        finally
        {
            // 服务停止时取消订阅,避免内存泄漏
            _eventService.RegEvent -= Log;
            _logger.LogInformation("Worker Service 已取消事件订阅");
        }
    }

    private void Log(string message)
    {
        // 使用事件传递的消息进行日志记录
        _logger.LogInformation("事件触发,消息内容:{Message}", message);
    }
}

2. 添加端点触发示例(API控制器)

用于触发事件的端点实现:

[ApiController]
[Route("api/events")]
public class EventTriggerController : ControllerBase
{
    private readonly IEventService _eventService;

    public EventTriggerController(IEventService eventService)
    {
        _eventService = eventService;
    }

    [HttpPost("trigger")]
    public IActionResult TriggerEvent()
    {
        _eventService.InvokeEvent();
        return Ok("事件已触发");
    }
}

3. 依赖注入配置

在Program.cs中注册服务,注意IEventService需要注册为单例,确保Worker Service和API控制器使用同一个实例传递事件:

var builder = WebApplication.CreateBuilder(args);

// 注册事件服务为单例
builder.Services.AddSingleton<IEventService, EventService>();
// 注册Worker Service
builder.Services.AddHostedService<WorkerService>();

// 添加控制器服务
builder.Services.AddControllers();

var app = builder.Build();

app.MapControllers();

app.Run();

关键说明

  • 生命周期管理:通过try-finally块确保服务无论正常停止还是异常终止,都会取消事件订阅,避免内存泄漏;
  • 事件传递可靠性:单例注册IEventService保证所有组件共享同一个事件实例,触发的事件能被Worker Service接收到;
  • 业务逻辑对齐:Log方法使用事件传入的参数,符合事件驱动的业务需求。

内容的提问来源于stack exchange,提问作者Arshaluys

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 09:48:15