Getting Started with Reactive Extensions (part 4)

This is the forth and final post in the series about RX

  • part 1 – Intro
  • part 2 – Mouse Events
  • part 3 – Complex Collection Events
  • part 4 – Client Server Async
  • </ul>

    Demo – Client Server Async events

    Consider the following situation. I have a WCF server and a Windows (or web client). The client can dispatch service request to the server and the server returns an async response. Now, when the user dispatches many requests at the same time for the same data, I only want to get one response from the server. As you can see in the image below, I only get one answer for all my calls. 


    Let’s look at the client code (Ctor of main windows in this case)

     public MainWindow()
        DataContext = _vm = new MyViewModel();
        //create instance of my WCF service
        _service = new MyService.MyServiceClient("BasicHttpBinding_IMyService");
        //register with weak reference to the button click event (instead of using myButton.Click += MyRoutedEventHandler(sender, eventArgs)           
        var buttonClick = Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(h => myButton.Click += h, h => myButton.Click -= h);
        buttonClick.Subscribe(s => 
        //Observer my async service method (AddOne)
        var myAsyncServiceCall = Observable.FromAsyncPattern<int /*service input*/, int /*service output*/>(_service.BeginAddOne, _service.EndAddOne);
            .Select(s => _counter) //we dont care for s which is of type RoutedEventArgs, we want to "work" on the _counter instead
            .Throttle(TimeSpan.FromSeconds(1)) //wait for 1 secods to see that nothing happend
            .SelectMany( t=> myAsyncServiceCall(t).TakeUntil(buttonClick)) //select the result from the observer we declared above
            .DistinctUntilChanged() //distinct
            .ObserveOnDispatcher() //work on UI thread
            .Subscribe(s => //what to do with the result
                _counter = s;

    As you can see I register to the button click event using reactive. This ensures I have a week reference observing an event, which can come quite handy when working with view models where strong references can cause a memory leak at some points. I didn’t have to do it, I could just “+=” the Button click event, but again, this is just to demo RX so hence the event subscription.

    Next, I observe from async pattern (my WCF service begin and end methods). Then take the button click observer, change the context to my _counter (using the Linq Select on the second line). Throttle the event for 1 second to see that the user has stopped clicking the button. Then I use SelectMany to get a response from the server async event until (TakeUntil) the button is clicked again; In this case, I discard the response and keep selecting till a new response arrives to my final button click event.

    The rest is pretty self-explanatory (you can download the code at the end of this post).

    Well, that’s it. This concludes 4 posts on getting started with RX. Personally, I found RX very helpful in many cases. It’s not the answer to everything, but can sure be helpful in today’s async world.

    There are many emerging frameworks for instance: RX UI, and MVVM I strongly encourage you to evaluate whether you need RX here and there or want to have a complete solution with RX. In many cases you would probably only need a tweak here and there…

    Code for this demo