The citation of the block text pretty much explains why you shouldn't use Subject<T> , but, simply put, you combine the observer functions and the observables, while at the same time introducing some kind of state between them (regardless of whether you are encapsulating or extension).
Here you have encountered difficulties; these responsibilities must be separate and distinct from each other.
However, in your particular case, I would recommend that you divide your problems into smaller parts.
First, you have your stream that is hot, and always monitor the hardware for alerts to boost notifications. How would you do that? Events . So let's start with this.
Determine EventArgs that your event will fire.
// The event args that has the information. public class BaseFrameEventArgs : EventArgs { public BaseFrameEventArgs(IBaseFrame baseFrame) { // Validate parameters. if (baseFrame == null) throw new ArgumentNullException("IBaseFrame"); // Set values. BaseFrame = baseFrame; } // Poor man immutability. public IBaseFrame BaseFrame { get; private set; } }
Now the class that will fire the event. Note that this could be a static class (since you always have a thread controlling the hardware buffer) or something that you call on demand that subscribes to it. You will need to change this if necessary.
public class BaseFrameMonitor {
So now you have a class that provides the event. Observables work well with events. So much so that there is first-class support for converting event streams (think of the event stream as several event errors) into IObservable<T> if you follow standard event patterns using the static FromEventPattern method on the Observable class .
With the source of your events and the FromEventPattern method FromEventPattern we can easily create IObservable<EventPattern<BaseFrameEventArgs>> (the EventPattern<TEventArgs> class embodies what you see in a .NET event, in particular, an instance received from EventArgs and an object representing the sender), eg:
Of course, you want an IObservable<IBaseFrame> , but it's easy using the Select extension method in the Observable class to create a projection (just like in LINQ, and you can wrap all this in a simple way):
public IObservable<IBaseFrame> CreateHardwareObservable() {