Reading msdn about the Reactive Extensions and such, I've found a recommendation saying I shouldn't implement IObservable, rather use Observable.Create... By the time I've read this, my project already had an ObservableImplementation<T> class, which I'd used as an IObservable source, everywhere I wanted to transform events into Observables.
I've read the AbstractObservable<T> implementation in System.Reactive, and I haven't found any major difference between their code and mine. So what's wrong with implementing IObservable? I can add my own properties to it, and so on...
for fullness sake, here is my implementation, please tell me if I did anything wrong!
public sealed class ObservableImplementation<T> : IObservable<T>
{
class Subscription : IDisposable
{
private readonly Action _onDispose;
public Subscription(Action onDispose)
{
_onDispose = onDispose;
}
public void Dispose()
{
_onDispose();
}
}
public void Raise(T value)
{
_observers.ForEach(o => o.OnNext(value));
}
public void Completion()
{
_observers.ForEach(o => o.OnCompleted());
_observers.Clear();
}
private readonly List<IObserver<T>> _observers = new List<IObserver<T>>();
public IDisposable Subscribe(IObserver<T> observer)
{
var subscription = new Subscription(() => _observers.Remove(observer));
_observers.Add(observer);
return subscription;
}
public bool AnyObserverPresent { get { return _observers.Any(); } }
}
There are a few reasons why we don't recommend people to implement IObservable<T> directly.
One is the lack of protection against violations of the observer grammar. For example, your sequence can exhibit behavior of OnNext calls following an OnCompleted call, which is invalid. The Observable.Create<T> method and ObservableBase<T> base type take care of this, by automatically detaching the observer upon receiving a terminal message. So even if your code does the wrong thing, the observer is not seeing a malformed sequence.
Btw, this is similar to iterators in C#. Implementing IEnumerable<T> manually should be such that when an enumerator's MoveNext returns false (analogous to OnCompleted), subsequent calls don't change their mind and start returning true (analogous to OnNext):
If MoveNext passes the end of the collection, the enumerator is positioned after the last element in the collection and MoveNext returns false. When the enumerator is at this position, subsequent calls to MoveNext also return false until Reset is called. (Source: MSDN)
When using iterators in C# 2.0 or VB 11.0, such concerns are taken care of for you. This is similar to our Observable.Create<T> method and ObservableBase<T> base type.
A reason related to the discussion above is clean-up. Upon returning from a Dispose call on a subscription, will the observer no longer see any messages? Upon sending a terminal message into the observer, will the Dispose logic for the related subscription be called automatically? Both are non-trivial to get right, so our base implementation takes care of that.
Another reason has to do with our CurrentThreadScheduler, ensuring that Subscribe calls can be asynchronous when running on that scheduler. Essentially, we need to check whether we need to install a trampoline on the current thread during a call to Subscribe. We don't expect everyone to know about this and do the right thing.
In your particular case - as noticed by others here - you're building pretty much a subject. Either just use one of our subjects, or wrap it by containment in your own type (e.g. if you want the sending "observer" side to be accessible by other parties than the receiving "observable" side).
The reason you shouldn't implement IObservable<T> is the same reason you don't usually implement IEnumerable<T>, is that somebody has most likely already built the thing you want. In this case, you've basically reimplemented Subject<T> for the most part.
Edit: As to the Lazy question in the comments, I'd implement that this way:
var lazyObservable = Observable.Create<TFoo>(subj => { /*TODO: Implement Me to load from reflection*/ })
.Multicast(new Subject<TFoo>()) // This means it'll only calc once
.RefCount(); // This means it won't get created until someone Subscribes
A recent blog post from the Rx team contains three reasons. Because it is a lengthy post I have copied the relevant parts.
Enforce the contract
Observable.Create takes in a single delegate that will become the core
implementation of the Subscribe method on the resulting IObservable
implementation. We do some clever wrapping around this delegate to
enforce the observer contract, amongst other things (which is why you
shouldn’t implement the interface yourself).
Wrapper for disposable
The returned disposable has a little wrapper around it, used to ensure
the observer won’t be called anymore after returning from the Dispose
call, even though the scheduler may not be at a good stopping point
yet. (Yet another reason you should never implement the IObservable
interface by hand. Oh, and by the way, there’s even more!)
Auto dispose on completion
The point of interest here is the auto-dispose behavior that’s applied
to the source subscription upon sending the OnCompleted downstream.
(This is yet another reason why manual implementation of
IObservable is strongly discouraged. When using
Observable.Create, we take care of this for you.)
Related
I am trying to learn how to work with Zenject's and unity and I have encountered a particular problem that I do not know if it has a possible solution solely using Zenject's api.
Let assume i have MethodA, MethodB and MethodC, and a SignalA.
Is it possible to make this sequence:
SignalA.Fire() => MethodA (until released/finished)
=> MethodB (until released/finished)
=> MethodC (until released/finished)
Right now i have this pice of code :
private void BindSignalA()
{
Container.DeclareSignal<SignalA>().RunSync();
Container.BindSignal<SignalA>().ToMethod<MethodA>(handler => handler.Execute).FromNew();
Container.BindSignal<SignalA>().ToMethod<MethodB>(handler => handler.Execute).FromNew();
Container.BindSignal<SignalA>().ToMethod<MethodC>(handler => handler.Execute).FromNew();
}
And MethodA looks like this :
public class MethodA
{
public async void Execute()
{
await new WaitUntil(() => false);
}
}
So the expected result is that MethodB and MethodC will be never executed.
But the actual result is that all Methods are executed.
Is there a solution using Zenject's api to make this happen?
Thanks for the help, and in case any more information is needed I would love to know.
I am not familiar with signals, but checking the documentation , mainly the the 3rd point into consideration maybe your case is not good scenario for signal use.
When To Use Signals
Signals are most appropriate as a communication mechanism when:
There might be multiple interested receivers listening to the signal
The sender doesn't need to get a result back from the receiver
The sender doesn't even really care if it gets received. In other words, the sender should not rely on some state changing when the signal is called for subsequent sender logic to work correctly. Ideally signals can be thought as "fire and forget" events
The sender triggers the signal infrequently or at unpredictable times
On the other hand I you might be confusing decoupling the code with the syncronous execution concept. Delegates or events (which are a specific type of delegate) are spare pieces of logic of one class that you can keep so that can be executed in other class, so that you can "subscribe" or "listen" to something that might happen to execute/invoke your event in other part of the code. However that does not involve any asyncronous code or multithreading.
As far as I can guess, signals are used to handle event subscription/invocation in a decoupled manner with the Zenject signal object, in a similar way as dependencies between classes are handled in a decoupled manner with interfaces, so first I would check if your case is suitable for their use checking the documentation carefully and following the examples provided along until the concept clicks.
Meanwhile, I would first try to use c# normal delegates so that after the zenject signal misson can be understood. Also providing a simple working example of what you are trying to do without zenject would be very helpful as departing point to achieve the zenject way of achieving that same thing.
This is potentially a very stupid question, but I'm not sure if I should be holding on to the IObservables generated by the Linq extension methods. Most of the examples seem to do so by default, but what would happen in a long running program. I have two examples to explain my question:
My first, and currently default implementation, involves subscribing to an IObservable provided by a pub\sub event aggregator. I'm comfortable with this because I know the observable will be around as long as the aggregator is.
protected virtual void SubscribeToEvents()
{
_subscriptions.Dispose();
_subscriptions = new CompositeDisposable();
IDisposable sendSubscription = Events.GetStream<OutgoingByteMessage>()
.Subscribe(msg =>
{
if (msg.Identifier.ChannelId == this.Id)
{
var queueItem = Tuple.Create(msg.Identifier.ConnectionId, msg.Data);
_sendQueue.Enqueue(queueItem);
}
});
_subscriptions.Add(sendSubscription);
}
However, if I use Linq to break down some of that logic, I can do this to get a subscription:
IDisposable altSendSubscription = Events.GetStream<OutgoingByteMessage>()
.Where(msg => msg.Identifier.ChannelId == this.Id)
.Select(msg => Tuple.Create(msg.Identifier.ConnectionId, msg.Data))
.Subscribe(item =>
{
_sendQueue.Enqueue(item);
});
My question is, on that second version, should I be keeping the product of that .Select method? This is happening in a method, afterall, so technically wouldn't the IObservable being returned there go out of scope as soon as SubscribeToEvents complete and be eligible for garbage collection? Or does the IDisposable object itself keep a reference to it, thereby making it safe to not keep a concrete reference to it somewhere.
After looking at the Rx source it looks like they use a series of forwarder classes to accomplish the Linq magic but I'm still a little paranoid. What do you guys think?
At the end of the day, all of the IObservable objects are being held via the list of subscribers on Events.GetStream (depending on your implementation of Events.GetStream, of course). Whether this goes out of scope depends on your implementation.
However, holding the IDisposable almost certainly keeps the subscription in scope as well, so even if your implementation was return Observable.Never<OutgoingByteMessage>, it would still exist because of the IDisposable.
You usually don't have to worry about active subscriptions going out of scope - the thing you should worry instead about is, subscription leaks. These occur when you subscribe to a global object (like something returned from an IoC container) and don't disconnect the subscription (and if the Observable never terminates).
This sounds like it'd not happen often, but it comes up more than you'd expect. For example:
MessageBus.Current.Listen<FooMessage>()
.Where(x => x.Bar == "Baz")
.Subscribe(x => Console.WriteLine(x));
If I put that in a constructor of some object that gets created all the time, I create dozens of subscriptions that never get cleaned up.
No, you do not need to worry. Think about it like this: as long as there is a source of events, the observable chain cannot be collectable since the act of subscribing links them all together. That is, each operator subscribes to the one above creating an observer it's parent references.
You don't even need to hold on to the subscription handle (altSendSubscription).
Why not use a memory profiler and look at the heap to convince yourself?
I am at the early stages of learning about Rx and have come across the Subject class. I don't quite understand why this class exists. I understand that it implements both IObservable and IObserver but what are Subjects used for?
As far as I can tell, they can act as a proxy between a source and a bunch of subscribers but couldn't the subscribers just subscribe directly to the source? When I see instances of a Subject being used as an observable and observer I get confused.
I am sure I am just not getting some basic fact here but I don't know what Subject brings to the game. I guess I am looking for some basic (but hopefully real world) example of when Subjects are useful and when they are not (as I have also read that Subjects are not usually used, replaced with Observable.Create).
First, a lot of folks will tell you Subject<T> doesn't belong, since it goes against some other tenets/patterns in the Rx framework.
That said, they act as either an IObservable or an IObserver, so you get some useful functionality out of them - I generally use them during the initial development stages for:
A "debug point" of sorts, where I can subscribe to an IObservable chain inline with a Subject<T>, and inspect the contents with the debugger.
An "observable on demand", where I can manually call OnNext and pass in data I want to inject into the stream
Used to use them to replicate what ConnectableObserable now does - a "broadcast" mechanism for multiple subscribers to a single Observable, but that can be done with Publish now.
Bridging layer between disparate systems; again, this is largely unnecessary now with the various FromAsync, FromEvent extensions, but they can still be used as such (basically, the "old" system injects events into the Subject<T> via OnNext, and from then on the normal Rx flow.
Using subjects means we are now managing state, which is potentially mutating. Mutating state and asynchronous programming are very hard to get right. Furthermore many of the operators (extension methods) have been carefully written to ensure correct and consistent lifetime of subscriptions and sequences are maintained. When you introduce subjects you can break this.
A significant benefit that the Create method has over subjects is that the sequence will be lazily evaluated.
In this example we show how we might first return a sequence via standard blocking eagerly evaluated call, and then we show the correct way to return an observable sequence without blocking by lazy evaluation.
Below example will be blocked for at least 1 second before they even receive the IObservable, regardless of if they do actually subscribe to it or not.
private IObservable<string> BlockingMethod()
{
var subject = new ReplaySubject<string>();
subject.OnNext("a");
subject.OnNext("b");
subject.OnCompleted();
Thread.Sleep(1000);
return subject;
}
Where as in bleow example consumer immediately receives the IObservable and will only incur the cost of the thread sleep if they subscribe.
private IObservable<string> NonBlocking()
{
return Observable.Create<string>(
(IObserver<string> observer) =>
{
observer.OnNext("a");
observer.OnNext("b");
observer.OnCompleted();
Thread.Sleep(1000);
return Disposable.Create(() => Console.WriteLine("Observer has unsubscribed"));
//or can return an Action like
//return () => Console.WriteLine("Observer has unsubscribed");
});
}
I'm going through the Head First Design Patterns book and doing my best to convert the code from their Java to C#. After the book discussed the observer pattern it mentioned that Java has classes/interfaces built in, as does .NET4. So I began researching how to use it properly and I have most of it figured out except for the Subscribe() method.
If you look at the MSDN Article when you try subscribing an IObserver, the method returns an IDisposable. Why would that be necessary? Why not just implement a method that unsubcribes the IObserver based on a method argument? I researched the reason to use an IDisposable interface. I also read this but didn't quite understand the difference/what it was trying to tell me:
It returns a reference to an IDisposable interface. This enables
observers to unsubscribe (that is, to stop receiving notifications)
before the provider has finished sending them and called the
subscriber's OnCompleted method.
The information that is required to cancel a subscription will vary depending upon how the event publisher manages subscriptions. The approach used for events--passing to the Remove method the delegate previously passed to the Add method--is kinda sorta workable, but has some significant deficiencies. Among them:
It will often require the event publisher to perform a linear search to locate the record which contains information related to the subscription. If there's a possibility of an event having many subscribers, this could create O(N^2) behavior needlessly. If subscribers are kept in some kind of linked list (either linked objects or index-linked array slots) and the unsubscribe request holds information about the subscription to be canceled, subscriptions and unsubscriptions can both handled in constant time. Further, unsubscription can be handled safely and easily in lock-free non-blocking fashion (using one `CompareExchange` on what will most likely be an uncontested array slot) that can safely be done in a `Finalize` context.
If one delegate gets subscribed multiple times to an event where the order of processing matters, and code tries to cancel the first subscription, the last subscription will get canceled and the first one will remain in effect.
If a delegate `D` is subscribed, a multicast delegate `ABCD` containing `A`, `B`, `C`, and `D` is subscribed, and then `D` is unsubscribed, then delegates `DABC` will remain subscribed, in the order, even if code tries to unsubscribe `ABCD`. Note that one could avoid this problem if one used a `List` instead of `delegateType.Combine`, but the other issues would remain.
Having the event subscription method return an object that can be used to cancel the subscription avoids these problems. The biggest question then becomes what type of object should be used. Three choices come to mind:
A delegate (probably parameterless, returning `void`)
Some `ICancelSubscription` interface, with a single method (probably parameterless, returning `void`) to cancel the subscription
`IDisposable`, an interface which exists, has a single parameterless method, and is widely used for cleanup-related purposes
Using a delegate would be a reasonable choice. It could be easily encapsulate whatever information was necessary to cancel a subscription without the user having to worry about what form that information might take. Using a delegate would entail the allocation of at least one extra heap object (for the delegate itself) and possibly two (the second being an object holding the unsubscription information). Using IDisposable would be essentially the same as using a delegate, except that one would call Dispose rather than Invoke; in many cases, though, IDisposable would have a slight advantage in terms of efficiency. Using some other interface would also be workable, but wouldn't really offer any advantage over using the existing IDisposable.
It seems that your main question here is why Microsoft choose:
interface IObservable<T>
{
IDisposable Subscribe(IObserver<T> observer);
}
instead of
interface IObservable<T>
{
void Subscribe(IObserver<T> observer);
void Unsubscribe(IObserver<T> observer);
}
While I am not privy to the design meetings or the reasonings that came out of them, I can speculate some reasons why this choice was made.
The best reason I can think of for choosing the first format is that it allows you to track only the IDisposable returned from Subscribe rather than both the observable and observer. For example, suppose you had code like this:
var obsSource = /* some observable source */
var subscription = obsSource.Where(x => x != null).Subscribe(Console.WriteLine);
// stuff...
subscription.Dispose();
In this situation, I never need to hold a reference to the subscribed to observable (returned from Where) nor explicitly create an observer (via the Subscribe extension method). If the second option had been chosen, you would have to do this instead:
var obsSource = /* some observable source */
var filtered = obsSource.Where(x => x != null);
var observer = Observer.Create(Console.WriteLine);
filtered.Subscribe(observer);
// stuff...
filtered.Unsubscribe(observer);
On the surface, this does not look too different, but as I discussed in another question, intermediate observables need not be kept once the subscription is made. If the second approach were taken, you would still need to create and keep observers for each step in the chain, and you would also have to keep references to the intermediate observables.
Version 1 makes the duality with IEnumerable easier to see than method 2. This may have been part of the initial design, but it is certainly a less important reason for the long haul.
A pair of Subscribe and Unsubscribe methods would be non-compositional. Every operator would need to keep a dictionary of observers that were passed in to Subscribe, mapping those onto each observer instance that was passed to dependent observable sequences (passed in to the operator).
For example, consider writing a Merge operator for two sources. Today, this looks pretty much like this (textarea compiled):
static IObservable<T> Merge<T>(IObservable<T> xs, IObservable<T> ys)
{
return Observable.Create<T>(observer =>
{
var n = 2;
var mergeObserver = Observer.Create<T>(
observer.OnNext,
observer.OnError,
() =>
{
// protected by the gate, see use of Synchronize below
if (--n == 0)
observer.OnCompleted();
}
);
var gate = new object();
return new CompositeDisposable(
xs.Synchronize(gate).Subscribe(mergeObserver),
ys.Synchronize(gate).Subscribe(mergeObserver)
);
});
}
As you can see, composition of sequences also leads to composition of the IDisposable objects returned from the Subscribe calls. Notice there's a lot of stuff going on in Observable.Create that automatically disposes the returned IDisposable upon sending a terminal message to the given observer. In this case, calls to observer.OnError and observer.OnCompleted take care of disposing both subscriptions in the CompositeDisposable. (But that's a whole different subject to talk about some time.)
The code below is hypothetical, assuming the existence of Subscribe/Unsubscribe pairs on IObservable (hence with a Create factory method that has two actions):
static IObservable<T> Merge<T>(IObservable<T> xs, IObservable<T> ys)
{
var map = new Dictionary<IObserver<T>, IObserver<T>>();
return Observable.Create<T>(
subscribe: observer =>
{
var gate = new object();
var n = 2;
var mergeObserver = Observer.Create<T>(
x =>
{
lock (gate)
observer.OnNext(x);
},
ex =>
{
lock (gate)
observer.OnError(ex);
},
() =>
{
lock (gate)
if (--n == 0)
observer.OnCompleted();
}
);
//
// Using .Synchronize(gate) would be a mess, because then we need to
// keep the two synchronized sequences around as well, such that we
// can call Unsubscribe on those. So, we're "better off" inlining the
// locking code in the observer.
//
// (Or: how composition goes down the drain!)
//
xs.Subscribe(mergeObserver);
ys.Subscribe(mergeObserver);
lock (map)
map[observer] = mergeObserver;
},
unsubscribe: observer =>
{
var mergeObserver = default(IObserver<T>);
lock (map)
map.TryGetValue(observer, out mergeObserver);
if (mergeObserver != null)
{
xs.Unsubscribe(mergeObserver);
ys.Unsubscribe(mergeObserver);
}
}
);
}
Beware this is hypothetical; I haven't even thought about more edge cases, nor how this Create would work in order to clean up after itself upon a call to OnError or OnCompleted. Also, with Merge as an example we're lucky we don't have other resources to care about during "Unsubscribe" (e.g. scheduler jobs).
Hope this helps,
-Bart (Rx team)
Calling an unsubscribe method means that you need to pass in the same instance that subscribed. You have to keep a reference. If you have many observables of different type you need many different references kept.
Clean up code becomes messy with an unsubscribe method.
However, with IDisposable you only need one structure to hold all references - List<IDisposable> (or you can use Rx's CompositeDisposable).
Now your clean up code can be very neat and tidy.
I have gone further and created IDisposable instances for all clean up code - not just from Rx subscriptions. It makes life very easy.
In addition to the other reasons given, IDisposable lets you use a using block as well.
using (var subscription = source.Subscribe(observer))
{
// ...
}
It makes it very easy to ensure that the subscription for the observer is terminated when the observer itself is Disposed. Consider that Subscribe is usually called by the class that implements IObservable:
class MyObserver<Foo> : IObserver<Foo>, IDisposable {
private IDisposable _subscription;
public MyObserver(IObservable<T> eventSource) {
_subscription = eventSource.Subscribe(this);
}
// implementation of IObservable members here
public void Dispose() {
_subscription.Dispose();
}
}
Now, when my MyObserver instance is disposed, the subscription is going to automatically be disposed along with it:
public partial class MyGUIThing : Form {
private MyObservable<Foo> _observer = new MyObservable<Foo>(someEventSource);
// whatever else
}
When an instance of this form is created, a subscription is started. When the form is closed and the _observer is finalized, the subscription will automatically be disposed as well.
I wrote an implementation based on the examples at [ Rx DEVHOL202] and http : //rxwiki.wikidot.com/101samples#toc48
Here is my code. http://csharp.pastebin.com/pm2NAPx6
It works, but the calls to OnNext are not NonBlocking, which is what i would like to implement to simulate a network read and asynchronously handing off each chunk of bytes as it is read to a handler [ which is not shown here in full but might cache results and do further processing ].
What is a good way of doing that?
Once the Exception gets thrown, all the subsequent OnNext()s are not processed!!
If I dont explicitly exit the loop and indicate completion.
Why is this so?
I would strongly recommend against trying to implement your own IObservable. The implicit rules go beyond thread safety and into method call ordering.
Usually you would return IObservable instances from methods, but if you need a class that implements it directly, you should wrap a Subject:
public class SomeObservable<T> : IObservable<T>
{
private Subject<T> subject = new Subject<T>();
public IDisposable Subscribe(IObserver<T> observer)
{
return subject.Subscribe(observer);
}
}
1. You need to be careful about how you support this from your observer (as you may have shared data), but you can make your handling of the calls asynchronous in one of two ways:
Call ObserveOn(Scheduler.TaskPool) (or ThreadPool if you are pre-4.0) before you call Subscribe. This causes messages to be routed through a scheduler (in this case, a task)
Pass the IScheduler to the Observer constructor
Start an asynchronous task/thread from your subscriber
2. This is the expected functionality. The contract between IObservable and IObserver is (OnNext)* (OnCompleted | OnError)?, which is to say "zero or more calls to OnNext, optionally followed by EITHER OnCompleted or OnError". After OnCompleted|OnError, it is invalid to call OnNext.
All the operators in Rx (Where, Select, etc) enforce this rule, even if the source doesn't.
I'm not sure if I understand your question correctly, but why can't you just execute whatever logic you have on a different Thread, or if it's small enough push it on a ThreadPool?
Here is an example:
ThreadPool.QueueUserWorkItem(o=>
{
_paidSubj.OnNext(this); // Raise PAID event
});
I'm confused about the data type on Subject, I have never seen that class in C#... is it something that you created? Is OnNext an event that gets raised or is it just a method? If OnNext is an event, then you can use BeginInvoke to invoke it asynchronously:
_paidSubj.OnNext.BeginInvoke(this, null, null);
Update:
An important thing that will happen if you implement this kind of asynchronous behavior: if you notify an IObserver by passing the Order, you might actually have some inconsistencies when you try to read the data in the observer (namely the order buffer) while the Order continues to modify the buffer in its Read thread. So there are at least two ways to solve this:
Restrict access to the memory which will get modified by using locks.
Only notify the observer with the relevant information that you want it to see:
a. By passing the information as a value (not as a reference).
b. By creating an immutable structure that transmits the information.
P.S.
Where did you get Subject from? Is Subject supposed to be an OrderObserver?