如何在Rx中创建Observable「通道」?咨询移除冗余事件脚手架方案
无需依赖事件创建Rx Observable通道的方案
当然有!你完全可以摆脱传统.NET事件的冗余脚手架,直接用Rx的原生类型来实现简洁的Observable推送通道,这也是Rx设计时推荐的轻量化实现方式之一。
核心思路:用Subject<T>替代事件脚手架
Subject<T>是Rx里的核心类型,它同时实现了IObservable<T>和IObserver<T>接口:
- 作为
IObserver<T>,你可以直接调用它的OnNext()方法推送数据; - 作为
IObservable<T>,外部代码可以正常订阅它接收推送内容。
为了保证封装性,我们还可以用AsObservable()把Subject<T>包装成只读的IObservable<T>,避免外部代码随意调用推送相关方法。
修改后的简洁实现
class WithEvents { public class MyEvent {} // 内部用Subject作为推送通道 private readonly Subject<MyEvent> _eventSubject = new Subject<MyEvent>(); // 对外暴露只读的Observable,外部仅能订阅 public IObservable<MyEvent> TheEvents => _eventSubject.AsObservable(); public void Foo() { // 直接推送事件,完全无需依赖.NET事件 _eventSubject.OnNext(new MyEvent()); } }
代码细节说明
- 彻底移除了原来的私有委托
MyEventHandler和事件EventRaised,用Subject<MyEvent>替代了整个中转逻辑; TheEvents通过_eventSubject.AsObservable()对外提供,确保外部只能进行订阅操作,不会破坏内部的推送逻辑;Foo()方法里直接调用_eventSubject.OnNext()完成推送,逻辑更直接简洁,没有多余的脚手架代码。
额外提示
- 如果需要多线程场景下的线程安全推送,可以使用Rx提供的
ConcurrentSubject<T>(部分版本可能需要额外NuGet包支持); - 记得在类的生命周期结束时(比如实现
IDisposable接口)调用_eventSubject.Dispose(),避免内存泄漏。
内容的提问来源于stack exchange,提问作者xtofl
相关产品推荐
相关产品推荐

