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
Dzisiejszy post jest szczególny, gdyż to 15 post składający się na wyzwanie jakie podjąłem. Półmetek jest. Wiele pracy już zostało włożone, jeszcze więcej przede mną. Dziękuję wszystkim czytelnikom, i mam nadzieję, że udało mi się komuś pomóc.
Zostałem też sprowadzony do porządku. Nadmiernie obkładałem FB grupę, swoimi publikacjami. Wszystkie osoby jakie uraziłem tym działaniem przepraszam. I znacznie ograniczę wrzucanie swoich wypocin na publiczne grupy w mediach społecznościowych.
ConsoleKey
Dzisiaj zmienimy trochę podejście, i zaczniemy przechwytywać zdarzenia pochodzące od użytkownika. W tym celu stworzyłem klasę ObservableConsoleKey. Można zapisywać się na jej wewnętrzną listę. Tym samym po uruchomieniu nasłuchu na zdarzenia pochodzące wciskanych przycisków w konsoli. Będziemy mogli reagować.
1
2
3
4
public class ObservableConsoleKey : IObservable<ConsoleKeyInfo>, IDisposable
{
private bool _catchKeys;
private List<IObserver<ConsoleKeyInfo>> _observers;
Publikacja wciśniętych klawiszy na stłumień odbywa się w metodzie Start. Dodatkowo użyłem zmiennej logicznej do kontroli pętli odbierającej dane z klawiatury i dystrybuującej do zapisanych zainteresowanych obiektów.
Przy pomocy publicznej metody Stop możemy przerwać pętlę i tym samym pozwolić na zakończanie programu w konsoli.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void Start()
{
_catchKeys = true;
while (_catchKeys)
{
var currentKey = Console.ReadKey(true);
Publish(currentKey);
}
}
public void Stop()
{
_catchKeys = false;
Metoda jest bardzo prosta i w zasadzie zmienia zmienną logiczną _catchKeys na false.
Publikowanie wciśniętych klawiszy na strumień jest bardzo proste. Także użyte tutaj zostało LINQ i metoda ForEach. Jako parametr w wyzwalanej metodzie OnNext oczywiście przekazujemy przechwycony klawisz z konsoli.
1
2
3
4
private void Publish(ConsoleKeyInfo currentKey)
{
_observers.ForEach(observer => observer.OnNext(currentKey));
}
Pozostałe elementy w klasie ObservableKeyConsole, są bardzo podobne do tych użytych w poprzednich klasach generatorów: ObservableValentinesDay, ObservableTimeCounter.
Ostatni fragment kodu dotyczy sposobu użycia nowego publishera. Jest bardzo podobnie do poprzednich z tą różnicą, że do dyspozycji mamy dwie wyżej opisane metody Start i Stop. Dzięki nim możemy sterować zachowaniem obiektu obserwowanego.
Zapis na strumień wykonujemy standardowo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static void Main()
{
var observableProvider = new ObservableProvider();
observableProvider.ConsoleKey
.Subscribe(consoleKey =>
{
Console.WriteLine(consoleKey.Key);
if (consoleKey.Key == ConsoleKey.Enter)
{
observableProvider.ConsoleKey.Stop();
}
});
observableProvider.ConsoleKey.Start();
Wykonujemy tutaj także ekstra sprawdzenie czy wciśnięty klawisz to Enter i gdy tak właśnie jest to wówczas zatrzymujemy pętlę przechwytującą klawiaturę konsoli. I tym samym możemy zatrzymać działanie programu w sposób naturalny.
Zakończenie
Tooooooo bardzoooooo krótki post. Wybrałem temat dość prosty do implementacji. Nie zawsze trzeba klepać multum lini kodu. Czasem trzeba coś prostego stworzyć. I myślę, że jest to bardzo ciekawe rozwiązanie.
Często czuję tutaj potrzebę użycia kontenera (AutoFac). I być może pojawią się posty o takiej tematyce. Wówczas mielibyśmy już dostęp w dowolnym miejscu programu do obiektów obserwowanych. W przypadku ObservableConsoleKey dało by to możliwość korzystania z wprowadzanych na konsolę danych w dowolnym miejscu aplikacji. Ciekawa koncepcja…
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 - Marudzimy - Take
Następny: Programowanie Reaktywne - Kombinatorzy - Concat