Artykuł ten jest częścią serii artykułów na temat Programowania reaktywnego.
Zapraszam na GitHub-a.
Tematy
- Wstęp
- Zabawa z czasem - Timer
- Kto za tym stoi? - Scheduler
- Nie zapominaj - Subscribe
- Zabawa z czasem - Interval
- Zabawa z czasem - Buffer
- Zabawa z czasem - Delay
- Zabawa z czasem - Sample
- Zabawa z czasem - Throttle
- Zabawa z czasem - Timestamp/TimeInterval
- Tworzymy dane - Generators
- Tworzymy dane - Własna klasa publikująca
- Marudzimy - Skip
- Marudzimy - Take
- Łap To! - ConsoleKey
- Kombinatorzy - Concat
- Kombinatorzy - Repeat
- Kombinatorzy - Start With
- Kombinatorzy - Ambiguous
- Kombinatorzy - Merge
- Kombinatorzy - Zip
- Kombinatorzy - Switch
- Kombinatorzy - When-And-Then
- Kombinatorzy - Combine Latest
- Transformers - Select
- Transformers - OfType and Cast
- Transformers - Metadata
- Bileciki do kontroli - Unit Tests of Interval
- Bileciki do kontroli - Unit Tests of Observer Interval
- Bileciki do kontroli - Unit Tests of Create Cold/Hot Observable
- Szpryca - AutoFac
Wstęp
Wielokrotnie w swoim życiu stosowałem dwojakiego rodzaju wyzwalacze w celu cyklicznego wykonywania pewny czynności. Mowa tutaj o wykorzystaniu Timera lub Thread. Pierwszy z nich polega na utworzeniu klasy, która będzie cyklicznie co określony czas wyzwalała event.
Natomiast druga opcja to wykorzystanie wątku + pętli. Do pętli wrzucamy to co chcemy cyklicznie wykonywać, wzbogacone o opóźnienie czasowe np. Thread.Sleep(100).
Ale hola miało być o reaktywnym programowaniu!
Observable.Timer
W tej sytuacji z pomocą przychodzi Reactive Extensions oraz bogaty zestaw strumieni do cyklicznego wyzwalania reakcji na obserwatorach.
Pierwszy z nich dość prosty to Timer.
Tak teraz pora na pierwszy kodzik wykorzystujący Reactive Extensions. Jest on dostępny na repozytorium GitHub.
Jak stworzyć taki strumień do obserwowania? Jak go obserwować?
Tworzenie prostego strumienia dla Timer-a.
1
2
3
4
5
public TimerDueTimeAndPeriod(TimeSpan dueTime, TimeSpan period)
{
_className = this.GetType().Name;
_timerObservable = Observable.Timer(dueTime, period);
Zmienna _className wykorzystana jest jedynie do celów identyfikacji, wyrzucanych na konsole treści;).
A tak się zapisujemy na timer-ek.
1
2
3
4
_lambdaSubscribe = timerObservable.Subscribe(index =>
{
Console.WriteLine($"[{_className}] : From lambda: {index}");
});
Dzięki tej zmiennej: _lambdaSubscribe kasujemy zapis obserwatora na strumień publikowany przez obiekt obserwowany.
index to identyfikator publikowania treści dla subskrybentów. Po każdej publikacji zwiększany jest o 1.
Korzystamy tutaj z lambdy jednak nic nie stoi na przeszkodzie, by skorzystać z normalnej metody.
1
2
3
4
5
6
7
_methodSubscribe = timerObservable.Subscribe(OnTimer);
}
private void OnTimer(long index)
{
Console.WriteLine($"[{_className}] : From lambda: {index}");
}
Zmienna _methodSubscribe jest nam potrzebna do późniejszego zniszczenia subskrybowanego strumienia.
Powyższe fragmenty kodu znajdują się w klasie: TimerDueTime.
To najprostsze użycie Timera ma jedną wadę. Wykona się tylko raz po upływie określonego czasu dueTime.
Ale zawsze można coś zaradzić. Przecież mamy takie coś jak przeciążanie operatorów:D
1
2
3
4
5
public TimerDueTimeAndPeriod(TimeSpan dueTime, TimeSpan period)
{
_className = this.GetType().Name;
_timerObservable = Observable.Timer(dueTime, period);
Dochodzi kolejny parametr period, określa powtarzanie publikacji co określony czas (nie należy zapomnieć, iż rozpocznie się to dopiero po upłynięciu dueTime).
Tym sposobem mamy do dyspozycji ładny timer-ek z wykorzystaniem RX-ów.
Zakończenie
Pierwsze koty za płoty. Myślę, że na dzisiaj wystarczy. Jednak nie jest to Całkowie wyczerpanie tematów Timer-ów. W kolejnym poście opiszę czym są Schedulery, czyli kolejny parametr, jaki możemy przekazać w metodzie Observable.Timer(…).
Zapraszam na GitHub do przejrzenia mojej “twórczości”.
Czym innym, jak nie współczesną poezją jest programowanie? Jako dowód: także w tym procederze, nie jest rzadkością pytanie. Co autor miał na myśli - twórczości interpretowanie.
Jest to post wchodzący w skład podjętego wyzwania ogłoszonego przez MIROBURN we vlogu z dnia 3 lutego 2018 roku.
Celem wyzwania jest systematyczne działanie w ciągu 30 dni.
Postanowiłem pisać post dziennie o tematyce Programowania Reaktywnego dla platformy .NET.
Wszelkie źródła związane z postami znajdują się na repozytorium GitHub.
Stan obecny wyzwania: 30 z 30 dni.
Referencje:
- MSDN - Getting Started with Rx,
- MSDN - Reactive Extensions,
- 101 Rx Samples,
- ReactiveX,
- Code Project,
- GitHub
Wcześniejszy: Programowanie Reaktywne - Wstęp.
Następny: Programowanie Reaktywne - Kto za tym stoi? - Scheduler.