Reactive Extensions–jak wygenerować proste źródła danych

W poprzednim poście pokazałem jak dokonać subskrypcji aby otrzymywać powiadomienia o nowych danych oraz jak skonwertować IEnumerable to IObservable. Dzisiaj chciałbym pokazać kilka metod klasy Observable, które są szczególnie ważne przy pisaniu testów jednostkowych oraz przy nauce RX.  Muszę przyznać, że na co dzień korzystam wyłącznie tylko z kilku z nich ale w przypadku UnitTest’ów są już bardzo praktyczne.
Observable to zbiór statycznych metod (często rozszerzających) usprawniających pracę z IObservable\IObserver (dla przypomnienia oba interfejsy należą do .NET a nie RX).

1. Observable.Return

Return zwraca IObservable, który zawiera wyłącznie jeden element. Przykład:

IObservable<int> source=Observable.Return(54);
source.Subscribe(Console.WriteLine);

Na wyjściu zostanie wyświetlone 54. Można byłoby oczywiście stworzyć IEnumerable a potem skonwertować do IObservable za pomocą ToObservable (patrz poprzedni post), ale tak jest po prostu szybciej.

2. Observable.Never

Zwraca źródło danych nie zawierające żadnych elementów. Nigdy nie zostaną wywołane OnNext, OnCompleted czy OnError. Przykład:

var source = Observable.Never<int>();
source.Subscribe(Console.WriteLine, (error) => Console.WriteLine("Błąd"), () => Console.WriteLine("Koniec"));

3. Observable.Empty

Generuje pusty zbiór danych. W przeciwieństwie do Never, OnCompleted zostanie wywołany:

 var source = Observable.Empty<int>();
source.Subscribe(Console.WriteLine, (error) => Console.WriteLine("Błąd"), () => Console.WriteLine("Koniec"));

4. Observable.Range

Generuje liczby całkowite począwszy od zadanego indeksu:

var source = Observable.Range(5, 10);
source.Subscribe(Console.WriteLine, (error) => Console.WriteLine("Błąd"), () => Console.WriteLine("Koniec"));
// output to 10 liczb zaczynajacych się od 5.

5. Observable.Error

Tworzy zbiór danych, który zakończy się błędem. Z punktu praktycznego, po prostu OnError zostanie wywołany:

var source = Observable.Throw<int>(new ArgumentException());
source.Subscribe(Console.WriteLine, (error) => Console.WriteLine("Błąd"), () => Console.WriteLine("Koniec"));

6. Observable.Generate

Observable.Generate generuje liczby na podstawie dostarczonych warunków:

var source = Observable.Generate(0, i => i < 100, i => i + 5, i => i*2);
source.Subscribe(Console.WriteLine, (error) => Console.WriteLine("Błąd"), () => Console.WriteLine("Koniec"));

public static IObservable<TResult> Generate<TState, TResult>(
    TState initialState,
    Func<TState, bool> condition,
    Func<TState, TState> iterate,
    Func<TState, TResult> resultSelector
)

Parametry kolejno to: początkowy stan (wartość), warunek określający kiedy ma zakończyć się generowanie danych, funkcja (iterate) generująca następną wartość, selektor zwracający końcową wartość (w naszym przypadku będzie to liczba pomnożona przez dwa).

7. Observable.Interval

Funkcja generuje liczby całkowite co dany czas np.:

var source = Observable.Interval(TimeSpan.FromSeconds(1));
source.Subscribe(Console.WriteLine, (error) => Console.WriteLine("Błąd"), () => Console.WriteLine("Koniec"));

Na wyjściu otrzymamy wartości 0,1,2,3…n z częstotliwością równą jednej sekundzie.

W następnym wpisie pokażę już coś dużo bardziej praktyczniejszego – jak korzystać ze zdarzeń w RX. Zaprezentuję również kilka praktycznych i bardziej “zaawansowanych” zapytań.

2 thoughts on “Reactive Extensions–jak wygenerować proste źródła danych”

  1. Hej,
    może da radę zwiększyć szerokość strony? Nie zawsze firebug jest pod ręką a przeglądanie strony z kodami, które pernamentnie trzeba przewijać w poziomie jest męczące. Poza tym ustawione jest 760px. Bez przesady teraz minimalnym standardem rozdziałek monitorów jest raczej >1200*x, co pozwala ustawić sobie 1000-1100 width na blogu. Pozdrawiam

Leave a Reply

Your email address will not be published.