Updating Reactive Samples to 10425 build by ThinqLinq

Updating Reactive Samples to 10425 build

Today, I decided to take the plunge and update my WPF and Silverlight Reactive Extensions samples to the latest (at the time of this writing) build of Rx: version 1.1.10425.0. At this point, I have purposely left the phone samples on the blog targeting the original shipping bits, so they aren’t affected at this point.

(ED: the 1.0.10605 stable and experimental releases shipped as of 6/5/2011. Looking at the release notes, this update appears to have much less breaking changes beyond those in the 1.1.10425 build).

As discussed in the Rx Forum post, this update has quite a number of breaking changes. Lee Campbell has a nice post discussing a number of these changes. If you don’t care about the changes and just want to download the revised samples, head on over the Files page and try them out:

  • RX_Wpf
    Reactive Framework samples from the "Becoming an RxPusher with the Reactive Framework" talk. With the emergence of LINQ, we discovered the power and flexibility that comes from the IEnumerable interface. This pull model makes iterating over sets of data and performing filtering, transformation, and aggregation operations easy through LINQ. However, the pull model breaks down in asynchronous and event driven environments. In evaluating the options, we discovered that the IObserverable interface and the push model were effectively analogous to the pull model of IEnumerable. As a result, we can make event driven asynchronous programming easier and more declarative by using the Reactive Framework and LINQ to Events.

    (Uploaded on 6/8/2011 - File Size 183442)

  • RX_Silverlight
    Slides and demos for using the Reactive Framework in Silverlight 4.

To help you update your existing projects, I figured I would share a bit of my experience with this update.

First of all, remove the existing references to the old builds of RX, including System.CoreEx, System.Interactive, and System.Reactive. Next download the new build either by downloading it directly from the MSDN Data Development center, or by using the Nuget Package Manager and installing the Rx-Main package. You do want to be careful here, because the older 1.0.2856.0 build is still available via Nuget as well. There are some cases where you might need access to the older build, particularly in cases where you need access to the IEnumerable extenstions that were added to complement the new ones in IObservable, like .Do. Also, note that the RxJs library is not currently updated to agree with the new method names, so you will need the older packages for RxJs support as well.

Once you have the new package downloaded and installed, add a reference to the System.Reactive assembly in your solution.

You won’t need to remove imports or using clauses from your classes because the older builds of Rx built the extensions directly on top of the System.Linq namespace. In the new builds, the LINQ extensions are now in the System.Reactive.Linq namespace, so you will need to add an Imports/using clause to System.Reactive.Linq. If you used the ObserveOnDispatcher/SubscribeOnDispatcher methods, these have been replaced by the simpler ObserveOn and SubscribeOn. As a result, you may want to add an Import/using clause for System.Threading as well so that we can access the SynchronizationContext more directly. With that in place, change your calls to .ObserveOnDispatcher as follows:


ObserveOn(SynchronizationContext.Current)

Next, we need to update some of the Observable factory implementations that we have used to create observables. The Observable.FromEvent method has changed to more closely align with Observable.FromAsyncPattern and now uses “FromEventPattern”. For example, the Mouse drag-drop example that we discussed in this post, now starts out as follows:


Dim mouseDown = From evt In Observable.FromEventPattern(Of MouseButtonEventArgs)(image, "MouseDown")
                Select evt.EventArgs.GetPosition(image)
Dim mouseUp = Observable.FromEventPattern(Of MouseButtonEventArgs)(image, "MouseUp")
Dim mouseMove = From evt In Observable.FromEventPattern(Of MouseEventArgs)(image, "MouseMove")
                Select evt.EventArgs.GetPosition(Me)

Similarly, the Observable.GenerateWithTime method has now been refined to the more generalized Observable.Generate and uses a TimeSpan override to specify the time interval.

Another such simplification was made to the Buffering and Windowing operations that we used in this post, including BufferWithTime, BufferWithCount, WindowWithTime and WindowWithCount. Now we just have a common Buffer operator that returns an IObservable<IList<T>> and Window which returns an IObservable<IObservable<T>> implementation. We can use the overload resolution to determine if we are passing in a timespan or integer and use the appropiate flavor of Buffer and Window as necessary. As a result, we can change our sorting code to the following:


Dim segmented = Sensor.Buffer(TimeSpan.FromSeconds(3))
segmented.Subscribe(Sub(val)
FilteredList.ItemsSource = From v In val 
                           Order By v.SensorValue) 

One last item that I needed to change was to restore the Do extension method on IEnumerable because I have come to love that function. Fortunately, implementing Do is relatively easy. Unfortunately, the implementation relies on iterators, so we need to put that in a C# project. Here’s the definition of the new Do extension method:


public static class IEnumerableEx
{
   public static IEnumerable<T> Do<T>(this IEnumerable<T> source, Action<T> action)
   {
        foreach (T item in source)
        {
            action(item);
            yield return item;
        }
    }
}

I’m sure you may run into other issues when updating your projects due to the breaking changes. Refer to the forum post above if you need help on your particular issue.

Posted on - Comment
Categories: VB Dev Center) - Rx) -
comments powered by Disqus