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
Dzisiejszym bohaterem zostaje ostatnia para Transformers-ów. Są oni ze sobą ściśle powiązani. Można śmiało powiedzieć, żę występują między nimi relacje rodzinne. Rodzic i dziecko. Zapraszam do dalszego czytania w celu zgłębienia tajemnic rodzinnych;).
Materialize i Dematerialize
Przygotowałem trzy przykłady. Na początek przygotujemy strumienie, i przekażemy je do metod zawierających mięsko.
1
2
3
4
5
6
7
8
9
var subscribents = new List<IDisposable>();
var observableProvider = new ObservableProvider();
var observableStream = GeneratorFactory.CreateGenerator(0, 5, 1, 300);
Console.WriteLine("Press any keys (Enter to end stream).");
MetadataCreateGenerator(subscribents, observableStream);
MetadataManual(subscribents);
MetadataConsoleKey(subscribents, observableProvider);
W każdym z poniższych przykładów został użyty operator rodzica: Materialize. A dlaczego nazwałem go rodzicem? Tak samo jak dziecko musi mieć swojego rodzica podobnie jest z drugą metodą Dematerialize.
Podsumowując by użyć Dematerialize należy najpierw skorzystać z Materialize.
Powyższe metody wyświetlają dane w formie metadanych. Czyli ukazują w przypadku Materialize metodę jaka jest wywoływana oraz dane jakie zawiera. Oczywiście to jakie dane są wyświetlane zależy od strumienia. Jeżeli na strumień wrzucane są np. klasy. To wówczas nie otrzymamy jedynie nazwę klasy.
Druga metoda Dematerialize sięga głębiej i wyświetla jedynie parametry przekazane do metod: OnNext, OnError, OnCompleted.
Poniższy przykład dotyczy wykorzystania prezentacji w kontekście strumienia ConsoleKey.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static void MetadataConsoleKey(ICollection<IDisposable> subscribents, ObservableProvider observableProvider)
{
subscribents.Add(
observableProvider.ConsoleKey
.Materialize()
.DefaultPrint("MaterializeConsoleKey"));
subscribents.Add(observableProvider.ConsoleKey
.Materialize()
.Dematerialize()
.DefaultPrint("DematerializeConsoleKey"));
subscribents.Add(observableProvider.ConsoleKey
.Select(x => x.Key)
.DefaultPrint("ConsoleKey"));
Po wduszeniu klawisza na klawiaturze, wyświetli się dwie formy metadanych oraz faktyczny klawisz jaki został wduszony.
Drugi przykład jest prostszy i bazuje na strumieniu pochodzącym z Generatora. W tym przypadku podobnie wyświetlone zostaną dane oraz metadane.
1
2
3
4
5
6
7
8
9
private static void MetadataCreateGenerator(ICollection<IDisposable> subscribents,IObservable<int> observableStream)
{
subscribents.Add(observableStream.Materialize()
.DefaultPrint("MaterializeCreateGenerator"));
subscribents.Add(observableStream
.Materialize()
.Dematerialize()
.DefaultPrint("DematerializeCreateGenerator"));
Ostatni z przykładów jaki przygotowałem dotyczy manualnie generowanego strumienia. I tutaj możemy zaobserwować jak zostanie potraktowany wyjątek i wywołanie OnError.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static void MetadataManual(ICollection<IDisposable> subscribents)
{
var source = new Subject<string>();
source.Materialize()
.DefaultPrint("MaterializeManual");
source.Materialize()
.Dematerialize()
.DefaultPrint("DematerializeManual");
source.OnNext("Tekst 1");
source.OnNext("Tekst 2");
source.OnError(new Exception("Wyjątek"));
source.OnCompleted();
W powyższym przykładzie wykorzystane zostały wszystkie metody jakie zostały zaimplementowane z interfejsu: IObserver.
Zakończenie
Powyższe operatory mogą być bardzo przydatne do analizy problemów. Można zalogować jakie typy danych zostały wtłoczone na strumień. W innym kontekście nie widzę zastosowania: Materialize, Dematerialize.
Dziękuję za czytactwo i zapraszam do śledzenia moich blogowych poczynań…
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 - Transformers - OfType and Cast
Następny: Programowanie Reaktywne - Bileciki do kontroli - Unit Tests of Interval