The difference between the observed cold at RX and the normal Enumerated

I am new to Rx. I see some real benefits of using Hot Observables, however, I was recently asked the question of what is the difference between observable by cold and equivalent enumeration (see code snippet below) ...

var resRx = Observable.Range(1, 10); var resOb = Enumerable.Range(1, 10); 

Can anyone explain very simply what the difference between the two is and what benefit I will get from the cold observable and enumerated.

+6
source share
2 answers

There are several differences between them.

Who controls the "listing"

With an observable (hot or cold) observable, it determines when and on which stream values ​​are returned. An enumerable, on the other hand, gets each value when you request it, and is processed in the stream requesting the enumeration.

Code stream

Enumerated jumps are usually performed in for each loop (or occasionally getting an enumerator and using a while loop). Typically, your code processes all values ​​before continuing. Observatories require a callback. Blocking the further execution of your code (for example, to save it from exiting the console application) requires additional code on your part. There are some blocking operators for observables, such as First , but they are the exception rather than the rule for normal use.

Take this trivial example program as an example. With an enumerated value, all values ​​are written before moving on to the next part. However, values ​​from the observed are not guaranteed. How many values ​​are written before the end of the program, this is largely a condition of the race.

 static void Main(string[] args) { var xs = Enumerable.Range(1, 10); foreach (var x in xs) { Console.WriteLine(x); } //at this point, all values have been written var ys = Observable.Range(1, 10); ys.Subscribe(y => Console.WriteLine(y)); //at this point, no values have been written (in general) //either add a Console.ReadKey or some sort of wait handle that //is set in the OnCompleted of the observer to get values } 

Asynchronous processes

Like you, you need to write additional code to lock and wait for the observable; additional work is required to write IEnumerable using an asynchronous process. That's where the difference between the two really comes into play.

For example, in the application in which I am currently working, I need to find devices that can be connected to the serial port. IObservable is suitable for this because it allows me to make a callback and notify the application for each device when I find it without locking and completing the operation. This observation qualifies as a cold observation because it will not output data if it does not have a subscriber, and each subscription receives all the results. (Unlike the usual observed cold, I start work before subscribing, but the data is not lost, because it is buffered in the subject of the replay). However, it would not make sense for me to convert it to Enumerable due to the asynchronous nature.

+15
source

Nearly all the transfers you are used to are cold transfers? What for? Because if you were in ForEach twice through Enumerable.Range, you would get 2x numbers.

If Enumerable.Range is Hot Enumerable, it will provide you with a list only once, and the second ForEach will just be empty.

For Rx, Cold Observable means that every time you call Subscribe (the equivalent of ForEach in Rx), you get a new list of things. Hot Observables like FromEvent won't give you a new event stream every time you subscribe, it will just be a different connection to the same event stream.

What is the advantage of Rx here? Ability to convert this range to async requests:

 IObservable<Image> fetchImageByIndex(int imageIndexOnSite); Observable.Range(0, 10) .SelectMany(x => fetchImageByIndex(x)) .Subscribe(image => saveImageToDisk(image)); 
+6
source

Source: https://habr.com/ru/post/896037/


All Articles