TechDays 2011 : LA PROGRAMMATION ASYNCHRONE – PART I : REACTIVE EXTENSIONS

Premier jour des Techdays 2011, pour ma première session je vais assister à une présentation du Framework Reactive Extensions ou Rx créé par les DevLab Microsoft.
La session est animée par Charlotte Chavancy, Jérémy Alles développeurs chez Tallès à Grenoble et Mitsu Furuta.

Dans l’ensemble la session a été très intéressante et très bien présentée, pas a pas.

Je vais donc essayer de rester dans le même esprit pour à mon tout vous démontrer la puissance de ce framework.

Les points importants à retenir :

Première démo :

Voici le code de base du quel nous allons partir.
Un timer est instancié est à chaque Tick on écrit la date courante dans la console.

Ok ce code ne sert à rien … c’est pas le sujet !
Nous allons maintenant le modifier pour implémenté le pattern Observable, puisque Rx repose entièrement sur ce dernier.

Avant de vous montrer le code, une petite explication du pattern s’impose.

C’est finalement assez simple, un objet de type Observer implémentant IObserver va souscrire à un objet de type Observable implémentant IObservable.

Regardons ces deux interfaces

Notre objet Observer va s’inscrire sur l’objet observable en apellant la méthode Subscribe() , puis l’observable va appeler les méthodes void OnCompleted(), OnError(), OnNext() de ses observers (oui il peut y en avoir plus d’un évidemment).

voici le résultat

Jusqu’ici rien de bien formidable. Patience on y va crescendo.

Revenons au principe de base, ce que l’on souhaite, c’est de faire des appels asynchrones de façon simplifiés.
Imaginons par exemple que notre application nécessite l’exécution d’une action assez longue même que l’on ne souhaite pas bloquer pour autant le thread principal.
Pour prendre un cas plus concret, lancer le téléchargement d’une image provenant de flickr sans freezer l’interface utilisateur. En winform, le backgroundWorker nous est d’une grande aide.
Cela revient à utiliser un système de callback via différents évènements.
Essayons de reproduire ce concept dans une application console via le Rx.

Une petite explication s’impose.
J’utilise ici la classe statique Observable qui fournit toute une collection de méthodes très intéressantes dont une utilisé ici Start(Func function).
Cette méthode permet d’invoquer très simplement une fonction et de créer un objet Observable.
Comme dans les exemples précédents il suffit alors de souscrire à cet objet.
La boucle for juste en dessous n’est là que pour montrer l’exécution asynchrone de l’appel.

Le résultat est le suivant :

Pas mal non ?
La programmation est assez simple finalement, on commence par coder de façon synchrone puis lorsque tout fonctionne on fait appel à la classe Observable par exemple pour créer un IObservable et s’y abonner

Mais ce n’est pas fini ! Allons encore un peu plus loin. Rx donne la possibilité de créer des IObservable directement à partir d’évènement.
Voici un petit exemple de ce qu’on peut faire pour créer un système de drag&drop en Silverlight.

Whoua !
Expliquons quand même la requête qui semble tiré par les cheveux.

from pos in mouseMove(rectangle)
Récupère un IObservable à partir de MouseMove sur le rectangle

.SkipUntil(mouseDown(rectangle)
Ignore les valeur tant que le MouseLeftButtonDown n’a pas renvoyé d’info

.Do(mb => rectangle.CaptureMouse())
Capture la souris pour permettre de faire fonctionner correctement le drag ..

.Do(mb => DropShadowStory1.Begin())
Lance le storyboard sur le rectangle
Les deux .Do() sont executés lors du MouseLeftButtonDown

.TakeUntil(mouseUp(rectangle)
Utiliser les valeurs tant que MouseLeftButtonUp n’a pas renvoyé d’infos

.Do(mb => DropShadowStoryReverse1.Begin())
Lance le storyboard inverse sur le rectangle

.Do(mb => rectangle.ReleaseMouseCapture())
Relache la souris, Les deux .Do() sont executés lors du MouseLeftButtonUp

.Let(mm => mm.Zip(mm.Skip(1), (prev, cur) =>
new
{
X = cur.EventArgs.GetPosition(this).X -
prev.EventArgs.GetPosition(this).X,
Y = cur.EventArgs.GetPosition(this).Y -
prev.EventArgs.GetPosition(this).Y
})).Repeat()
select pos;
Tout ce bloc permet de sélectionner le déplacement entre deux points.
La méthode Zip prend deux séquences pour les assembler en une seule, il faut donc sauter la première séquence puisque la valeur précédente n’existe pas.
Ensuite un simple calcule est effectué.

Dans le subscribe il suffit d’appliquer le déplacement et le tour est joué.

Bon je vous l’accorde ça ne sert clairement à rien, ce n’est que pour la démo. On peut arriver exactement au même résultat en ajoutant un simple MouseDragElementBehavior sur notre élément.

Voici le résultat.
Le rectangle vert correspond au code avec Rx.
Le rectangle rouge correspond au Behavior.

[silverlight: TechDays2011.Rx.SilverlightApplication.xap]

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Vous pouvez utiliser ces balises et attributs HTML : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">