Reactive Extensions Partie 1 : Introduction
Me revoila après quelques mois sans poster sur ce blog. Vous l'avez probablement remarqué, la programmation parallèle est en plein essor. Le nombre de coeurs dans nos processeurs ne cesse d'augmenter, et les jours sont maintenant comptés avant qu'on ait des processeurs quadricores jusqu'à dans nos téléphones. Il est donc nécessaire pour les développeurs d'adapter la façon même de concevoir et écrire des logiciels.
Microsoft n'est pas insensible à cette problématique et a déjà fait un grand pas avec le Parallel FX, qui sera partie intégrante du .NET Framework 4.0. La TPL en particulier permet d'écrire des programmes parallèles beaucoup plus confortablement que ça n'était le cas avec .NET 3.5. Mais même si il s'agit d'une avancée serieuse, il manquait toujours quelque chose pour unifier tous les differents modèles de programmation asynchrone, et surtout pour les orchestrer et les coordinner.
C'est pour cette raison que les Reactive Extensions (aussi appelées RX) ont vu le jour. Il s'agit d'une librairie sortie de DevLabs. Elle fonctionne avec .NET 3.5, .NET 4.0 et Silverlight 3. Cette librairie est construite autour de deux interfaces clés : IObservable<T> et IObserver<T>. Ces deux interfaces seront intégrées dans .NET 4.0.
IObservable est en fait très similaire à IEnumerable, elle représente une collection. Mais là où IEnumerable représente une collection synchrone ("Pull"), où le consommateur choisit quand il veut la prochaine valeur (MoveNext / Current), IObservable représente une collection asynchrone. L'IObservable décide quand une nouvelle valeur est disponible, et la fournit au consommateur ("Push").

public interface IObservable<T>
{
IDisposable Subscribe(IObserver<T> observer);
}
public interface IObserver<in T>
{
void OnCompleted();
void OnError(Exception error);
void OnNext(T value);
}
IObservable fonctionne de la manière suivante :
- Le consommateur dispose d'une instance d'un objet qui implémente IObservable (collection asynchrone)
- Le consommateur appelle la méthode Subscribe en passant un IObserver (qui peut être assimilé à un "super-callback")
- Lorsque la collection décide qu'une nouvelle valeur est disponible, elle appelle la méthode OnNext de l'IObserver en passant la valeur en paramètre (ceci se produit pour chaque valeur dans la collection)
- Lorsque la collection a été complètement énumerée avec succès, elle appelle la méthode OnComplete de l'IObserver, ou, si une erreur s'est produite, elle appelle la méthode OnError de l'IObserver en passant les détails de l'exception
Cela semble surement très abstrait, voici donc un exemple :
Commençons par implémenter un IObserver :
public class ConsoleObserver : IObserver<string>
{
public void OnCompleted()
{
Console.WriteLine("OnCompleted");
}
public void OnError(Exception error)
{
Console.WriteLine("OnError");
}
public void OnNext(string value)
{
Console.WriteLine("OnNext: " + value);
}
}
Cet observeur affiche les valeurs qu'il reçoit dans la console.
Créons maintenant un IObservable. Il y a des centaines de façons différentes de créer des IObservables en utilisant RX. Voici l'une d'elles :
IObservable<string> observable = Observable.Return("Hello");
Cette ligne crée un observable qui génère instantanément la valeur "Hello", puis termine (OnCompleted).
Souscrivons maintenant à cet observable en utilisant notre ConsoleObserver:
IObserver<string> observer = new ConsoleObserver();
observable.Subscribe(observer);
Voici ce qui s'affiche sur la console :
OnNext: Hello
OnCompleted
Les auteurs de RX ont fait en sorte que toute opération possible sur un IEnumerable existe aussi pour IObservable (si elle a du sens), voici donc un exemple de ce qu'il est possible de faire:
IObservable<string> observable = from value in Observable.Range(0, 100)
select "Hello " + value.ToString();
Cet observable va générer instantanément 100 valeurs puis termine. Il n'y a cependant rien de terriblement asynchrone dans les deux exemples ci-dessus.
IObservable<string> observable = from value in Observable.Interval(TimeSpan.FromSeconds(1))
select "Hello " + value.ToString();
Celui-ci par contre, génère une valeur toutes les secondes, et ne termine jamais.
J'entrerai plus dans les détails sur IObservable et les Reactive Extensions dans mes prochains articles.
Télécharger RX : http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx
Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :