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

C#中如何通过注入接口实现对Timer Elapsed事件的响应?

解决接口无法包含实例字段实现Timer事件响应的问题

C#接口不允许定义实例级字段,只能声明方法、属性、事件这类成员,这就是你遇到报错的原因。下面提供两种可行的实现方案:


方案一:在接口中声明事件

直接在接口里定义事件,实现类将内部定时器的Elapsed事件与接口事件关联,外部服务通过接口订阅事件即可。

1. 修改接口

public interface ILocalPermissionManager
{
    event ElapsedEventHandler TimerElapsed;
}

2. 实现类代码

public class LocalPermissionManager : ILocalPermissionManager
{
    private readonly Timer _validityTimer;
    
    // 实现接口的事件
    public event ElapsedEventHandler TimerElapsed;

    public LocalPermissionManager()
    {
        _validityTimer = new Timer(5000); // 示例:5秒触发一次
        _validityTimer.Elapsed += ValidityTimer_Elapsed;
        _validityTimer.Start();
    }

    private void ValidityTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        // 触发接口暴露的事件,通知所有订阅者
        TimerElapsed?.Invoke(sender, e);
    }
}

3. 外部服务订阅事件

public class BusinessService
{
    public BusinessService(ILocalPermissionManager permissionManager)
    {
        // 订阅定时事件
        permissionManager.TimerElapsed += PermissionManager_TimerElapsed;
    }

    private void PermissionManager_TimerElapsed(object sender, ElapsedEventArgs e)
    {
        // 这里写你需要执行的定时逻辑
    }
}

方案二:通过方法封装订阅逻辑

如果希望更隐蔽地控制事件订阅(比如限制订阅次数、统一管理订阅者),可以在接口中定义订阅/取消订阅的方法,内部封装委托的添加和移除。

1. 修改接口

public interface ILocalPermissionManager
{
    void AddTimerHandler(ElapsedEventHandler handler);
    void RemoveTimerHandler(ElapsedEventHandler handler);
}

2. 实现类代码

public class LocalPermissionManager : ILocalPermissionManager
{
    private readonly Timer _validityTimer;
    private ElapsedEventHandler _timerHandlers;

    public LocalPermissionManager()
    {
        _validityTimer = new Timer(5000);
        _validityTimer.Elapsed += ValidityTimer_Elapsed;
        _validityTimer.Start();
    }

    public void AddTimerHandler(ElapsedEventHandler handler)
    {
        _timerHandlers += handler;
    }

    public void RemoveTimerHandler(ElapsedEventHandler handler)
    {
        _timerHandlers -= handler;
    }

    private void ValidityTimer_Elapsed(object sender, ElapsedEventArgs e)
    {
        _timerHandlers?.Invoke(sender, e);
    }
}

3. 外部服务使用

public class BusinessService : IDisposable
{
    private readonly ElapsedEventHandler _handler;
    private readonly ILocalPermissionManager _permissionManager;

    public BusinessService(ILocalPermissionManager permissionManager)
    {
        _permissionManager = permissionManager;
        _handler = PermissionManager_TimerElapsed;
        _permissionManager.AddTimerHandler(_handler);
    }

    private void PermissionManager_TimerElapsed(object sender, ElapsedEventArgs e)
    {
        // 执行定时逻辑
    }

    // 服务销毁时取消订阅,避免内存泄漏
    public void Dispose()
    {
        _permissionManager.RemoveTimerHandler(_handler);
    }
}

注意事项

  • 内存泄漏:如果订阅者生命周期长于发布者,或者反之,记得在合适时机取消订阅(比如在Dispose方法中),必要时可使用弱引用处理。
  • 线程安全:System.Timers.Timer的Elapsed事件在ThreadPool线程触发,处理共享资源时要加锁或使用线程安全的数据结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 13:42:40