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

如何在ASP.NET Core中使用delegate定义、触发和处理异步事件

异步事件(Async Events)的正确使用方式

一、核心概念梳理

异步事件本质是支持异步处理逻辑的事件系统,完全不需要强制使用静态类做处理程序——只要你的处理程序类能被实例化,就能注入依赖并完成事件注册。.NET框架提供了现成的AsyncEventHandler<TEventArgs>委托类型,专门用来定义异步事件,无需自定义基础委托。

二、分步示例实现

下面用「订单创建事件 + 带日志依赖的异步处理」场景做演示:

1. 定义事件参数类

创建事件触发时传递数据的类:

// 事件参数:传递订单创建的相关信息
public class OrderCreatedEventArgs : EventArgs
{
    public int OrderId { get; }
    public decimal Amount { get; }

    public OrderCreatedEventArgs(int orderId, decimal amount)
    {
        OrderId = orderId;
        Amount = amount;
    }
}

2. 创建事件发布者(触发事件的类)

定义负责触发事件的服务,用AsyncEventHandler<TEventArgs>声明事件:

public class OrderService
{
    // 声明异步事件:使用框架自带的AsyncEventHandler<T>
    public event AsyncEventHandler<OrderCreatedEventArgs>? OrderCreated;

    // 模拟创建订单的方法,完成后触发事件
    public async Task CreateOrderAsync(int orderId, decimal amount)
    {
        // 模拟订单创建的异步业务逻辑
        await Task.Delay(100);

        // 触发事件:先判断是否有订阅者,再异步调用
        if (OrderCreated != null)
        {
            await OrderCreated.Invoke(this, new OrderCreatedEventArgs(orderId, amount));
        }
    }
}

3. 创建带依赖的事件处理程序

处理程序类包含依赖(比如日志服务),并实现异步处理逻辑:

// 模拟日志服务接口
public interface ILogger
{
    Task LogAsync(string message);
}

// 模拟日志服务实现
public class ConsoleLogger : ILogger
{
    public async Task LogAsync(string message)
    {
        await Task.Delay(50); // 模拟异步日志写入
        Console.WriteLine($"[日志] {message}");
    }
}

// 带依赖的事件处理类
public class OrderCreatedHandler
{
    private readonly ILogger _logger;

    // 通过构造函数注入依赖
    public OrderCreatedHandler(ILogger logger)
    {
        _logger = logger;
    }

    // 异步事件处理方法:签名匹配AsyncEventHandler<T>
    public async Task HandleOrderCreatedAsync(object? sender, OrderCreatedEventArgs e)
    {
        // 每次事件触发时执行的逻辑
        await _logger.LogAsync($"订单 {e.OrderId} 已创建,金额:{e.Amount:C}");
        // 可添加其他异步操作:比如发送通知、更新统计数据等
        await Task.Delay(200);
    }
}

4. 注册事件并触发

在主程序中完成依赖初始化、事件注册和触发:

class Program
{
    static async Task Main(string[] args)
    {
        // 1. 实例化依赖服务
        ILogger logger = new ConsoleLogger();
        // 2. 实例化带依赖的处理程序
        OrderCreatedHandler handler = new OrderCreatedHandler(logger);
        // 3. 实例化事件发布者
        OrderService orderService = new OrderService();

        // 4. 注册事件:将处理程序的方法绑定到事件
        orderService.OrderCreated += handler.HandleOrderCreatedAsync;

        // 5. 触发事件:模拟创建两个订单
        await orderService.CreateOrderAsync(1001, 299.99m);
        await orderService.CreateOrderAsync(1002, 59.9m);

        Console.ReadLine();
    }
}

三、关键注意事项

  • 异步事件触发必须用await:如果直接调用OrderCreated?.Invoke(...)不await,会导致异步操作未完成就继续执行后续代码,还可能引发未捕获的异常。
  • 抛弃静态类误区:处理程序可以是实例类,通过构造函数注入依赖,注册事件时直接绑定实例方法即可。
  • 空事件判断:触发事件前一定要检查OrderCreated != null,避免空引用异常。
  • 多订阅者处理:多个处理程序注册到同一事件时,默认会串行异步执行,若需要并行可自行实现逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:06:04