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
相关产品推荐
相关产品推荐

