Tuesday 26 May 2009

Reacting to the Reactive Framework: Part 1

Last night I managed to get some code working and I was very excited, but it was far too late to start writing a blog post. Here is the code:

Func<MouseEventArgs, int> slowOperation = args =>
{
    System.Threading.Thread.Sleep(3000);
    return args.X;
};

IObservable<int> observable = from md in button1.GetMouseDowns()
                              from x in slowOperation.AsAsyncObservable(md.EventArgs)
                              select x;

Action<string> textboxUpdater = s => textBox1.AppendText(s);
observable.Attach(x => textBox1.BeginInvoke(textboxUpdater, "Mouse down: " + x + "\n"));

This code is sitting inside a very simple windows form. The form has a button and a textbox. When the button is clicked, a message is written to the textbox about 3 seconds later, relaying the relative X coordinate of the mouse when the button was clicked. The 3 second delay represents some sort of slow asynchronous operation, currently simulated with a simple Thread.Sleep(). Because the slow operation is done on a different thread, we have to use Control.BeginInvoke() to get the textbox to update on the UI thread. GetMouseDowns() is an extension method on Button that helps set the whole thing up by returning an IObservable that is wired to the MouseDown event.

So at this point you might be wondering what this is all about. To get the full story, I encourage you to watch Eric Meijer’s video on the LiveLabs Reactive Framework (direct wmv link). In this very enjoyable presentation, Eric gives us a run down the Reactive Framework, which appears to be a set of libraries that unite various types of “reactive” operations under a common pair of interfaces, IObserver<T> and IObservable<T> which are then integrated into LINQ. I found the presentation to be quite a tease. Erik shows just enough to give you an idea of what the Reactive Framework is all about, but he skims over the implementation details quite lightly. I ended up watching the thing a couple of times, trying to wrap my head around the idea of LINQ query comprehensions (e.g. from x in y select x.ID) operating against non enumerable/queryable types. In particular, I started wondering whether I could implement something like the code from this slide:

image

As you can see, my code at the top is not too dissimilar from Erik’s code here. Erik’s example is a web page with dictionary suggest on a textbox. When the user enters a character into the textbox, the dictionary suggest runs asynchronously against the input entered so far and when a return value is received it is rendered as html.

There is certainly quite a lot regarding the Reactive Framework that I don’t understand. I’ve been unable to find any resources beyond Erik’s talk – certainly the code doesn’t seem available anywhere. So far I don’t even understand how IObserver fits in. Can YOU see anything that might implement IObserver in the above slide? But in any case, the idea is intriguing, and trying to figure out how to do this myself is teaching me quite a bit about LINQ. In the next post, I’ll do my best to explain how the implementation works. Don’t forget your goggles, this is some pretty hacky code coming up.

7 comments:

  1. Paul, some great resources here -- http://themechanicalbride.blogspot.com -- and here -- http://blog.lap49.com

    Any reason why you've disabled paste in this comment box. And lots of other keys?? Or am I the only one? Didn't have the energy to type the full links, feel free to write me if you want them, via http://ramthemdown.wordpress.com

    ReplyDelete
  2. I haven't deliberately disabled them, its something that blogger seems to do and only some of the time, quite frustrating I know!

    Jafar's blog is great, I link to it in later posts of this series. I presume your other link was supposed to be http://blog.lab49.com/ ? I had a look but I couldn't see any reactive framework related content.

    ReplyDelete
  3. Hey, pasting works today!

    I think this is the link I had in mind:
    http://blog.lab49.com/archives/3252

    ReplyDelete
  4. Hey,

    Are you using Volta? :)

    I noticed the RunAtOriginAttribute.

    Can you elaborate on that?

    ReplyDelete
  5. That shot is a slide from Erik's talk, which I linked in the post. So it was Erik that was using Volta in that example, not I :)

    ReplyDelete
  6. Great site about Reacting to the Reactive Framework,this information really helped me , I really appreciate it,I will visit when ever i have found the stuff That i have been searching for in all the web for, keep up the great work!

    ReplyDelete
  7. This comment has been removed by a blog administrator.

    ReplyDelete