开发者

Real world examples of Rx [duplicate]

开发者 https://www.devze.com 2022-12-30 21:31 出处:网络
This question already has answers here: Closed 10 years ago. Possible Duplicate: Good example of Reactive Extensions Use
This question already has answers here: Closed 10 years ago.

Possible Duplicate:

Good example of Reactive Extensions Use

I've been playing around with the Reactive Extension for a little while now, but mostly limited to handling/composing user driven events wi开发者_如何学Pythonthin a WPF frontend.

It's such a powerful, new way of doing async programming, and I'm curious as to what other people are doing with it, and where do you think it might be able to improve the way we're currently doing things?


We used RX with great success on two projects (Silverlight UI) already. At the beginning the intent was to simplify the WCF access layer) The rational was that in the worse case scenario we can always revert back to standard (callback) ways of doing things without affecting higher levels of the UI.

Little did we know that RX is like an addictive drug - once you start using it there's simply no coming back. Like a virus it quickly spread from this low-level communication layer all the way up to UI components:

  • we started with simple syntactic sugar to make accessing WCF services simpler.
  • from there it was a natural step to extend RX to server-to-client async messaging
  • after that to use RX to merge both of these ways for client to communicate with the server into one so viewmodels are agnostic about how they receive messages was a default option.

And then it was complete capitulation:

  • need to handle messages coming out of order?
  • need to flash a cell on the grid when price changes?
  • have a performance issue because client is bombarded by messages from the server?
  • have some rudimental CEP logic to handle?

Well, guess what, there's RX operator for that ;) (and if there's not - you can easily just write one)

The hardest part of it all was to overcome that "my-brain-hurts-so-bad" feeling that everyone on our team experienced at the beginning. Brain of a mere mortal conditioned by years of handle-my-event-by-this-callback coding is just not wired the way RX sees the world. As the result RX code (especially once it progressively gets more and more dense while handling more and more complicated scenarios) for an unprepared mind looks like complete abracadabra that amusingly does result in a rabbit pulled out of a seemingly empty hat. Unfortunately, the reality is there's no place for magic in production running code and thus whole team must be on board, which means everyone will have to go through this painful process of rewiring their brains in what seems at first like a very unnatural way.

I'd say that it's a human factor and not the RX API itself that is the biggest obstacle on effectively adopting RX. But boy is it worth it!


I've written a more complete library for integrating WPF / Silverlight and Rx, the documentation is (EDIT: No longer lousy!) right now, but you can check it out at:

http://www.reactiveui.net


Samuel McAravey has a video on Channel9 describing a real-world SilverLight application he built using RX. He even made it available on CodePlex.

Also, here are a few of practical uses when you can apply RX even if you do not have asynchronous requirements:

  • If you want to allow user scroll through a list displaying some details on the side, querying for details synchronousely might hurt your scrolling performance. .Throttle() is your friend here.
  • Sometimes you need to perform a lookup as soon as user stops typing. Same thing, use .Throttle and you are fine.
  • Use Routed Commmands in MVVM. Very nice for using on list items, just specify CommandParameter="{Binding}" and you can catch these on the container level.


We are successfully using Rx when loading data from backend in a Silverlight app. We have recently migrated from a SOAP service plain XML-generation on the server and Rx came just in time so that we could use it instead of WebClient or WebRequest (actually we wrap WebClient in Observable right now, but will probably move to WebRequest).

We had a bug a couple of days ago; we realized that the request URLs were so long that they were truncated. Fortunately we can split the request in multiple ones and concatenate the responses, but solving that using only WebClient would have meant creating a queue and a state machine to handle requests in sequence... Instead, using Rx we could simply split the request in groups, do what we did before, but in a call to SelectMany and we were done! Rx to the rescue!


Probably my favorite solution right now for Rx is to use it as an event aggregator. Take a look here:

http://jfromaniello.blogspot.com/2010/04/event-aggregator-with-reactive.html

I adapted this to Silverlight and it works like a charm. What is amazingly powerful is the ability to filter events. For examle, one event is just type "string" because there is no other information. Instead of creating a strongly typed class for each simple event, I created a class that exposes the constants (so there are no magic strings) - for example, BEGIN_BUSY (when a web service is being called), END_BUSY (when it's done), etc.

To subscribe, you can literally do:

(from e in EventAggregator.Subscribe<string>() where e.Equals(BEGIN_BUSY) select true).Subscribe( evt=> { // Listening only to the BEGIN_BUSY event }); 

Love it!

0

精彩评论

暂无评论...
验证码 换一张
取 消