Programowanie Reaktywne - Zabawa z czasem - Timestamp/TimeInterval.

12.02.2018


Artykuł ten jest częścią serii artykułów na temat Programowania reaktywnego.

Zapraszam na GitHub-a.

Tematy

  1. Wstęp
  2. Zabawa z czasem - Timer
  3. Kto za tym stoi? - Scheduler
  4. Nie zapominaj - Subscribe
  5. Zabawa z czasem - Interval
  6. Zabawa z czasem - Buffer
  7. Zabawa z czasem - Delay
  8. Zabawa z czasem - Sample
  9. Zabawa z czasem - Throttle
  10. Zabawa z czasem - Timestamp/TimeInterval
  11. Tworzymy dane - Generators
  12. Tworzymy dane - Własna klasa publikująca
  13. Marudzimy - Skip
  14. Marudzimy - Take
  15. Łap To! - ConsoleKey
  16. Kombinatorzy - Concat
  17. Kombinatorzy - Repeat
  18. Kombinatorzy - Start With
  19. Kombinatorzy - Ambiguous
  20. Kombinatorzy - Merge
  21. Kombinatorzy - Zip
  22. Kombinatorzy - Switch
  23. Kombinatorzy - When-And-Then
  24. Kombinatorzy - Combine Latest
  25. Transformers - Select
  26. Transformers - OfType and Cast
  27. Transformers - Metadata
  28. Bileciki do kontroli - Unit Tests of Interval
  29. Bileciki do kontroli - Unit Tests of Observer Interval
  30. Bileciki do kontroli - Unit Tests of Create Cold/Hot Observable
  31. Szpryca - AutoFac

Wstęp

Reactive Extensions - Extension Methods To już ostatni post z rodziny timer-owatych. Omówione zostaną dwa proste operatory. Ale co ważniejsze, zaimplementujemy kolejne dwa własne. Rx oparty jest o rozszerzone metody, dlatego bardzo łatwo jest dodać kolejne potrzebne “stworki”.

TimeInterval, Timestamp

Pierwszy fragment kodu dotyczy oznaczania danych na strumieniu interwałem czasowym. Dzięki takiemu działaniu, można zaobserwować ile czasu upłynęło pomiędzy poszczególnymi danymi publikowanymi do obserwatorów. Po takiej konwersji otrzymujemy nie jedną, a dwa pola:

  • Value - to wartość podawana przez strumień bazowy,
  • Interval - okres jaki upłynął od ostatniego przetwarzania strumienia.

Przykład oczywiście na GitHub-ie w projekcie o nazwie StampAndInterval, a fragment poniżej.

1
2
3
4
5
6
7
8
9
10
11
12
13
var observableInterval = Observable.Interval(TimeSpan.FromSeconds(1));

_subscribeTimeInterval = observableInterval
	.TimeInterval()
	.Subscribe(
		x => Console.WriteLine("TimeInterval \t\t{0} \t{1}", x.Value, x.Interval)
	);

_subscribeTimestamp = observableInterval
	.Timestamp()
	.Subscribe(
		x => Console.WriteLine("Timestamp \t\t{0} \t{1}", x.Value, x.Timestamp)
	);

Reactive Extensions - Extension Methods Już wcześniej w postach korzystaliśmy z operatora opakowującego strumienie tak by uzyskać oprócz danych np. stempel czasowy. Do tego celu posłużyliśmy się operatorem: .Timestamp(). Po opakowaniu otrzymujemy dwie właściwości:

  • Value - to wartość podawana przez strumień bazowy,
  • Timestamp - czas danych publikowanych na strumień.

Extension Methods

Zajmiemy się teraz odwróceniem działania Timestamp(), TimeInterval(). W tym celu należy nieco się napocić, i zaimplementować własne rozszerzenia do interfejsu IObservable.

1
2
3
4
5
6
7
8
9
10
11
12
public static class RXExtensions
{
	public static IObservable<TSource> RemoveTimeInterval<TSource>(this IObservable<TimeInterval<TSource>> source)
	{
		return source.Select(x => x.Value);
	}

	public static IObservable<TSource> RemoveTimestamp<TSource>(this IObservable<Timestamped<TSource>> source)
	{
		return source.Select(x => x.Value);
	}
}

Po implementacji metod, należy nie marnować kodu i go użyć. Strumień w tym przypadku musi już posiadać odpowiednie opakowanie. W pierwszym przykładzie: RemoveTimestamp, należy opakować oczywiście Timestamp-em. I tak właśnie się dzieje w pierwszym przykładzie poniżej.

1
2
3
4
5
6
7
var observableInterval = Observable.Interval(TimeSpan.FromSeconds(1)).Timestamp();

_subscribeWithoutTimestamp = observableInterval
	.RemoveTimestamp()
	.Subscribe(
		x => Console.WriteLine("Remove Timestamp \t{0}", x)
	);

Analogicznie postąpimy z drugim przykładem, z tą różnicą że będziemy korzystać z operatorów dotyczących TimeInterval. Odpowiednio .TimeInterval() i .RemoveTimeInterval().

1
2
3
4
5
6
7
var observableInterval = Observable.Interval(TimeSpan.FromSeconds(1)).TimeInterval();

_subscribeWithoutTimeInterval = observableInterval
	.RemoveTimeInterval()
	.Subscribe(
		x => Console.WriteLine("Remove TimeInterval \t{0}", x)
	);

Zakończenie

Kończąc tą partie postów dotyczących czasu. Mam nadzieję, iż przysłużyłem się komuś moją malutką wiedzą na ten temat. W kolejnych poznawać będziemy inne mechanizmy, operatory jakie dostarczają biblioteki Reactive Extensions. Zapraszam do śledzenia. I dziękuję za obecność.


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:


Wcześniejszy: Programowanie Reaktywne - Zabawa z czasem - Throttle

Następny: Programowanie Reaktywne - Tworzymy dane - Generators


Zapisz się na listę :)