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

C#中如何订阅、处理并跟踪多个事件?(多设备场景下的实现咨询)

通用化多设备事件订阅的C#实现方案

我完全懂你的困扰——现在能单个设备订阅事件,但要扩展到多个设备时,重复写订阅代码不仅麻烦,还很容易搞混逻辑,毕竟socket.eventPool.Subscribe("flight", ...)这部分看起来都差不多。用类来封装每个设备的事件处理逻辑绝对是正确的方向,这样每个设备的订阅和业务逻辑都能独立管理,彻底避免混淆。

下面给你一套具体的实现方案,包含示例代码:

1. 先定义统一的处理器接口

首先我们给所有设备的flight事件处理器定义一个公共接口,保证结构一致,同时方便后续统一管理:

public interface IFlightEventHandler
{
    // 返回当前处理器对应的设备名称
    string TargetDevice { get; }
    // 每个设备专属的flight事件处理逻辑
    void HandleFlightEvent(object sender, flightArgs e);
}

2. 为每个设备实现专属处理器

接下来针对每个设备写具体的处理类,把该设备的业务逻辑完全封装在类里:

// Gulfstream设备的处理器
public class GulfstreamFlightHandler : IFlightEventHandler
{
    public string TargetDevice => "gulfstream";

    public void HandleFlightEvent(object sender, flightArgs e)
    {
        // Gulfstream专属逻辑:打印温度和高度
        Console.WriteLine($"[Gulfstream] 实时数据:温度 {e.STR1.temp}°C,高度 {e.STR1.alt}ft");
    }
}

// Boeing747设备的处理器
public class Boeing747FlightHandler : IFlightEventHandler
{
    public string TargetDevice => "boeing747";

    public void HandleFlightEvent(object sender, flightArgs e)
    {
        // Boeing747专属逻辑:打印数据+高度告警
        Console.WriteLine($"[Boeing747] 实时数据:温度 {e.STR1.temp}°C,高度 {e.STR1.alt}ft");
        CheckHighAltitudeWarning(e.STR1.alt);
    }

    private void CheckHighAltitudeWarning(double altitude)
    {
        if (altitude > 45000)
        {
            Console.WriteLine("[Boeing747] 告警:高度超过安全阈值!");
        }
    }
}

// 后续新增设备只需要加新的处理器类就行,比如AirbusA380
public class AirbusA380FlightHandler : IFlightEventHandler
{
    public string TargetDevice => "airbusa380";

    public void HandleFlightEvent(object sender, flightArgs e)
    {
        // AirbusA380的专属逻辑,比如写入数据库或者调用其他接口
        Console.WriteLine($"[AirbusA380] 记录数据:温度={e.STR1.temp},高度={e.STR1.alt}");
        // SaveToDatabase(e);
    }
}

3. 实现统一的事件管理器

写一个管理器类,负责把所有处理器注册到事件池,同时完成设备订阅。这样我们不需要重复写Subscribe和SubscribeEquip代码,所有逻辑都交给管理器处理:

public class FlightEventManager
{
    private readonly Socket _socket;
    // 保存处理器和对应的委托,方便后续取消订阅
    private readonly Dictionary<IFlightEventHandler, EventHandler<flightArgs>> _handlerDelegates = new();

    public FlightEventManager(Socket socket)
    {
        _socket = socket;
    }

    public void RegisterHandler(IFlightEventHandler handler)
    {
        if (_handlerDelegates.ContainsKey(handler)) return;

        // 创建绑定当前处理器的委托,确保只处理目标设备的事件
        var eventDelegate = new EventHandler<flightArgs>((sender, e) =>
        {
            // 这里假设flightArgs里包含设备标识,如果没有的话,可能需要你调整socket库的事件参数,或者通过其他方式区分
            // 如果实在无法从e中获取设备信息,也可以在订阅设备时通过闭包绑定,但这种方式依赖socket库的实现逻辑
            if (e.DeviceName == handler.TargetDevice)
            {
                handler.HandleFlightEvent(sender, e);
            }
        });

        // 订阅flight事件和对应的设备
        _socket.eventPool.Subscribe("flight", eventDelegate);
        _socket.SubscribeEquip(handler.TargetDevice);

        // 保存委托,方便后续取消订阅
        _handlerDelegates.Add(handler, eventDelegate);
    }

    public void UnregisterHandler(IFlightEventHandler handler)
    {
        if (_handlerDelegates.TryGetValue(handler, out var eventDelegate))
        {
            // 取消事件订阅和设备订阅
            _socket.eventPool.Unsubscribe("flight", eventDelegate);
            _socket.UnsubscribeEquip(handler.TargetDevice);
            
            _handlerDelegates.Remove(handler);
        }
    }
}

4. 最终使用示例

在主代码里,只需要实例化管理器和各个处理器,注册进去就完成了所有设备的事件订阅:

// 假设你已经有了Socket实例
var socket = new Socket();
var flightEventManager = new FlightEventManager(socket);

// 注册各个设备的处理器
flightEventManager.RegisterHandler(new GulfstreamFlightHandler());
flightEventManager.RegisterHandler(new Boeing747FlightHandler());
flightEventManager.RegisterHandler(new AirbusA380FlightHandler());

// 如果某个设备不需要监控了,直接取消注册
// flightEventManager.UnregisterHandler(boeingHandler);

额外优化建议

  • 如果多个设备的处理逻辑有公共部分,可以抽一个抽象基类BaseFlightEventHandler,把公共逻辑写在基类里,子类只需要重写差异化的部分。
  • 如果flightArgs里没有设备标识,你可以和socket库的提供者确认是否能添加,或者换一种方式:比如每个设备对应专属的事件名称(如flight_gulfstream),但这需要socket库支持。
  • 别忘了在设备不再需要监控时调用UnregisterHandler,避免内存泄漏。

这样一来,每个设备的逻辑都完全独立,新增设备只需要加一个处理器类,维护起来非常方便,再也不会出现逻辑混淆的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 06:42:49