How can I make my implementation of IObservable<T> multithreaded? - c#

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?

Related

Unity & Zenject - How to execute methods in sequence order from a TSignal.Fire()

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.

What to deal with multiple asynchronous method invocations in C#

Suppose, I have a simple class, with async method in it:
public class Writer
{
public Task WriteAsync(string message);
}
This is internal class, which is absolutely negligible for application's business logic.
The main idea of the method, is that when it's called - method must immediately returns control to the calling method, to avoid any possible delay in important, full of business logic calling method (delay for calling that method is possible of course).
This method calls in different places, very often. and we don't really care if it's successful or won't write last messages in case of unexpectable situation. That's fine.
So, the question is, how can I call WriteAsync to avoid any possible delays in calling method?
I thought about Task.Run(() => WriteAsync(message)) (without await! we don't need to wait this!), but won't that fill my thread pool with a lot of useless work? And it's quite onerously writing everywhere such code...
You may queue the writes and process the queue, i.e. perform the writing, on a dedicated background thread. This is kind of what happens when you call Task.Run, i.e. you queue up delegates in the thread pool. If you require more control, you may for example use a BlockingCollection<T>.
There is an example of how to use a BlockingCollection<T> to read and write items concurrently available on MSDN.
Using this approach, calling WriteAsync will only block for the time it takes to add the message to the queue and this time should be negligible.
Because the method is asynchronous then, by definition, it is already returning control to the caller immediately. If the implementation of that method isn't actually asynchronous, then it should either not return a Task, not have Async in the name, and make it clear to callers that it's synchronous, or it should fix the bug in its implementation that makes it block the caller for an extended period of time. Callers of the method will rightfully expect that, being an asynchronous method, it will return control to the caller immediately by just calling the method normally. If the method has a bug in it that makes it not do that, you shouldn't work around that bug and have callers treat it as a synchronous method when it claims it isn't.

Event Ordering in .NET

Got a quick question on event ordering in C#/.NET.
Let's say you have a while loop that reads a socket interface (TCP). The interface is definitely taking care of the ordering (it's TCP). Let's say your packet interface is written so that each "packet" you get in the stream, you will forward it to the next "layer" or the next object via an event callback.
So here is the pseudocode:
while (1) {
readsocket();
if (data received = complete packet)
raiseEvent(packet);
}
My questions are:
Are the events generated in order? (i.e. preserve ordering)
I am assuming #1 is correct, so that means it will block the while loop until the event finishes processing?
You never know how the event is implemented. It's possible that the events will all be executed synchronously, in order, and based on some meaningful value. It's also possible that they'll be executed synchronously in some arbitrary and inconsistent ordering. It's also possible that they won't even be executed synchronously, and that the various event handlers will be executed in new threads (or thread pool threads). It's entirely up to the implementation of the event to determine all of that.
It's rather uncommon to see different event handlers executed in parallel (and by that I mean very, very very rare), and almost all events that you come across will be backed by a single multicast delegate, meaning the order they will be fired in is the order in which they were added, but you have no way of actually knowing if that's the case (baring decompiling the code). There is no indication from the public API if that is how it is implemented.
Regardless of all of this, from a conceptual perspective, it would be best to not rely on any ordering of event handler invocations, and it's generally best to program as if the various event handlers could be run concurrently because at a conceptual level, that is what an event represents even if the implementation details are more restrictive.

Reactive extensions Subject uses

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");
});
}

Why shouldn't I implement IObservable<T>?

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.)

Categories

Resources