Mark Elston (132) [Avatar] Offline
#1
You mention at the bottom of page 207 that:

Unlike enumerables, observables can emit asynchronous notifications, so the order in which
the resultSelector is invoked is nondeterministic. This means that SelectMany will have to
cache all the items from the source observable in order to pass them with each one of the
notifications emitted by the observable they created.


I don't understand the reasoning here. Why would, for example, a hot observable have to cache anything any longer than is necessary to pass it along to all subscribers?
Tamir Dresher (35) [Avatar] Offline
#2
The overload for SelectMany that i'm talking about is the one where each item from the source observable is "mapped" to an asynchronous operation (in the form of a Task).
When the asynchronous operation completes, the resultSelector is invoked with the result of the operation and the source item that created it.
If the time it takes for each asynchronous operation to complete is "long" and during this time other items are emitted by the source observable, then the source items and the Tasks they created are still in memory. if the source items are "big", for example images, and the async operation is something like image processing that tries to find if the image is copyrighted (which can take some time), then if many images were emitted by the source observable in a given time, we end up having all those images in memory until the result of the processing is complete.

Did i help to make it more clear?
Mark Elston (132) [Avatar] Offline
#3
I'm not sure. The marble diagram just above the description would indicate that there is no need to cache anything as the observable results are passed to resultSelector as soon as they are available. Is that not the case? And, even in the paragraph you say the order in which resultSelector is called is nondeterministic which implies the same thing (sort of).

Maybe I'm missing the point here. The only thing that I see that needs to be cached in the example above this is the room observable which, in turn has the observable Messages that we want to associate with the room.

The way I read the paragraph in question was that not only would we need to cache the room observable but all the messages from the Message observable it contained as well. I don't understand why all the messages would have to be cached.

Did I read that incorrectly?
Tamir Dresher (35) [Avatar] Offline
#4
I understand the confusion now.
The messages themselves are not cached and each message is processed when it's available. but the room itself is kept in memory as long as its Messages observable is not complete.
This is not necessarily bad (and even desirable in many cases), but i saw more than once developers ask the question "why is my Rx query consume so much memory?" and then realize that they're keeping the source items (each room in our example) "alive", also when the SelectMany produces a Task (and not observable), developers sometimes miss the fact that multiple asynchronous operations might run concurrently, and each one of them consume resources.