Question

Given a BehaviorSubject, what is the practical difference between calling all of these different functions on it?

  • First()
  • Last()
  • LatestValue()
  • MostRecentValue()
  • NextValue()
  • Single()
  • Take(1)

Assuming I understand it right, they should all do about the same thing, given the BehaviorSubject.

If so, then which call is the most appropriate (by which I mean: which best communicates my intent)? First or Single perhaps?

If not, then what are the practical differences?

Was it helpful?

Solution

First, Last, and Single are blocking; it is recommended to use Take(1) instead, so you get an IObservable back. When chaining query operators it is recommended to avoid First, Last and Single because you exit the safety of the monad ... that is to say you have blocking side effects. See http://blogs.msdn.com/jeffva/archive/2009/12/09/first-last-contains-etc-can-be-extremely-dangerous-yet-extremely-useful.aspx for more about that.

MostRecentValue and LatestValue have been removed from the latest version of Rx because they are blocking as well, so the only blocking operators left are First, Last, and Single (and the xxxOrDefault variants), according to the latest release notes.

MostRecent will return the last value sampled, as often as you call it (and it takes an initialValue to guarantee it will never wait), i.e. "without consumption", whereas Latest will wait until a value arrives then return it "with consumption" - that is, if you call Latest again it will not return the same value as the last call, it will wait until the next value arrives, if ever.

OTHER TIPS

Thanks @RichardHein for the great answer.

The blocking extension methods should really be moved into their own namespace, so the developer has to specifically choose to include them for a project (or specifically a CS file). You add a ton of complexity with Rx, and by accidentally using a blocking method you're basically devolving back to IList/IEnumerable.

I think this is the biggest mistake the Rx team made, IOW I think by including these by default they missed the 'pit of success' with Rx. Fix this and I'd call Rx the API of choice when moving beyond single-threaded + async in C# (i.e. why .NET is more powerful than say NodeJS).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top