poniedziałek, 28 listopada 2011

[RX 1] Wprowadzenie do Reactive Extensions (RX) dla .NET - cz.1 [PL]

Jako że nie dawno przedstawiłem na spotkaniu Łódzkiej grupy profesjonalistów IT & .NET prezentację poświęconą „Wprowadzenie do Reactive Extensions (RX) dla .NET” (patrz informacja: Zapraszam na prezentację: "Wstęp do Reactive Extensions dla .NET (RX)" oraz Prezentacja i kod ze spotkania pt.: "Wprowadzenie do Reactive Extensions (RX) dla .NET" [PL]). Postanowiłem czytelnikom bloga „Programowanie i Technologie” również przybliżyć temat Reactive Extensions, więc jeżeli zdarzyło Ci się tworzyć aplikacje, które wykorzystywały wywołania asynchroniczne. Te asynchroniczne wywołania sprawiły problemy. Wolałbyś otrzymywać dane, zamiast o każdą daną się dopraszać. Znasz LINQ i nie zawahasz się go użyć w szerszym zakresie, to z pewnością powinienieś poznać bliżej Reactive Extensions (RX). Zapraszam do przeczytania pierwszej części serii postów poświęconych RX.

Wstęp, czyli odwieczny problem pobierania danych

Chyba każdy programista, tworzył kiedykolwiek aplikację, której jednym z zadań było pobieranie danych ze źródła danych. Ta popularna i prosta z pozoru czynność, zwykle wygląda następująco – wysyłamy żądanie o porcję danych, następnie czekamy na odpowiedź i odbieramy danych. Takie podejście może się jednak wiązać z pewnymi problemami, z którymi należy się zmierzyć. Wśród ważniejszych wymienić należy sytuację, gdy po wysłaniu żądania, żadne dane nie zostaną odesłane lub odesłane zostaną po nieakceptowalnym dla nas czasie.
Wyobraźmy sobie sytuację (która została przedstawiona na poniższym rysunku), w której aplikacja po naciśnięciu przycisku wysyła żądanie o dane do odległej bazy danych, która znajduje się w chmurze obliczeniowej. Gdy dane zostaną odesłane natychmiast być może użytkownik nie zauważy niczego niepokojącego. Co jednak w przypadku, gdyby dane nie zostały odesłane lub czas, po którym zostały odebrane, przekroczyłby czas wyznaczony przez cierpliwość użytkownika? Zwykle aplikacja zdawałaby się nie działać, o czym system operacyjny Windows poinformowałby nas komunikatem podobnym do: „Program .... nie odpowiada. Trwa wyszukiwanie rozwiązania przez system Windows.”. W konsekwencji pewnie otrzymalibyśmy zapytanie, czy zamknąć program, czy poczekać, aż program zacznie odpowiadać. Chyba nikt z nas nie lubi takich pytań (na które nie ma prostej odpowiedzi). Chyba nikt z nas, programistów, nie chciałby, by ich aplikacje działały w ten sposób.
Zastanówmy się jednak, dlaczego taka sytuacja mogła mieć miejsce. Otóż nasza aplikacja odpytywała źródło danych w sposób synchroniczny lub prościej, na każde zapytanie oczekiwana była od razu odpowiedź. Aplikacja została zablokowana, gdyż po wysłaniu żądania o dane, oczekiwała na odpowiedź, która nie nadeszła lub nadejść miała po akceptowalnym czasie.

Asynchroniczność

W poprzednim przykładzie jednym ze źródeł problemów było synchroniczne podejście do pobierania danych. Oczywiście innym sposobem na pobieranie danych jest wykorzystanie podejścia asynchronicznego. Otóż okazuje się, że wiele problemów, można rozwiązać stosując właśnie podejście asynchroniczne. Dzisiejszy świat zdaje się być stworzony do komunikacji asynchronicznej. Przecież nie chcemy być blokowani w oczekiwaniu na kolejną daną. Zauważmy ponadto, że źródeł danych może być wiele, może zajść sytuacja, w której musimy połączyć dane z wielu z nich.
Dlatego trudno się nie zgodzić, że:
  • Asynchroniczność jest potrzebna niemal wszędzie.
  • Asynchroniczne programowanie jest trudne.
  • Komponowanie asynchronicznego kodu jest jeszcze trudniejsze.
Wyobraźmy sobie sytuacje, w której asynchroniczne obsługujemy sieciowe źródło danych i jeśli się to powiedzie, to robimy coś tam, a jeśli się nie uda to coś innego. No i jeszcze, gdy dorzucimy do tego, że np. wszystko musi się wykonać w czasie mniejszym niż 10 sekund, gdyż w przeciwnym razie nie będziemy zainteresowani wynikiem. Musimy więc składać/komponować zdarzenia, jednak jest to bardzo trudne. Ponadto możemy nie być zainteresowaniu wszystkimi danymi, będziemy chcieli je wybierać, czy filtrować. I oczywiście jesteśmy przyzwyczajeni do prostych rozwiązań, a przecież najłatwiej przeglądać po prostu kolekcje danych.

Misja Reactive Extensions

Wróćmy jednak do głównego tematu, czyli „Reactive Extensions”. Otóż na głównej stronie tego projektu (http://msdn.microsoft.com/en-us/data/gg577609) można znaleźć następującą definicję:
„The Reactive Extensions (Rx)...
...is a library to compose asynchronous and event-based programs using observable collections and LINQ-style query operators.”
Definicja ta krótko i zwięźle podsumowuje, czym jest Rx, ale przyznam, że musiałem przeczytać ją kilkakrotnie, zanim zrozumiałem detale. W każdym razie Reactive Extensions pozwalają na:
  • Uproszczenie kodu związanego z programowaniem asynchronicznym oraz opartym na zdarzeniach,
  • Dają możliwość filtrowania lub komponowania (łączenia) różnych asynchronicznych operacji oraz ich wyników (np. z wykorzystaniem LINQ).
  • Oferują inne podejście do obsługi kolekcji oraz zdarzeń. W Rx są one traktowane jako źródła danych, które możemy obserwować.
Skąd jednak wziąć owe biblioteki dla Reactive Extensions? Niestety Rx nie jest częścią .NET 3.5 SP1 ani .NET 4.0. Można jednak dla tych frameworków pobrać odpowiednie biblioteki, co więcej w .NET 4.0 wprowadzono już pewne elementy związane z podstawami Rx. Również w przypadku Silverlight można skorzystać z Rx, aktualnie wspierana jest wersja Silverlight 4 i eksperymentalnie Silverlight w wersji 5, natomiast wersja Silverlight 3 była wspierane przez starsze wersje Rx. Co ciekawe Rx jest dostępne standardowo w ramach systemu Windows Phone 7 i jest zainstalowane w pamięci ROM urządzenia (nie trzeba nic dodatkowo pobierać, czy instalować). Dostępna jest również specjalna wersja Rx dla Java Script (RxJS). Dla kompletności można również wspomnieć o platformie XNA 3 i 4, które były wspierane przez starsze wersji Rx, ale wsparcie to nie będzie już kontynuowane. W tym artykule skupimy się jednak na wersji Rx dla .NET.
Reasumując Rx można zainstalować przy pomocy programu instalacyjnego dostępnego pod adresem: http://www.microsoft.com/download/en/details.aspx?id=26649 (trafić tu można przez MSDN > Learn > Reactive Extensions (http://msdn.microsoft.com/en-us/data/gg577609 ) > Get it) lub prościej przy użyciu NuGet'a (wyszukujemy Rx).
c.d.n. ...
Promuj

2 komentarze:

Posty powiązane / Related posts