Ten artykuł jest lustrzanym artykułem tłumaczenia maszynowego, kliknij tutaj, aby przejść do oryginalnego artykułu.

Widok: 2585|Odpowiedź: 2

[Źródło] Poznaj tematy w rozszerzeniu .Net Reactive Responsive

[Skopiuj link]
Opublikowano 27.01.2024 12:17:19 | | | |
Rozszerzenie .Net Reactive oferuje deweloperom zestaw funkcji umożliwiających wdrożenie reaktywnego modelu programowania dla twórców .Net, aby ułatwić i uczynić obsługę zdarzeń bardziej ekspresyjną przy użyciu akcji deklaratywnych. Choć kluczowymi filarami skalowania reaktywnego są interfejsy IObserver i IObservable, jako programista często nie musisz samodzielnie implementować tych interfejsów. Biblioteka obsługuje wbudowany typ Subject<T>, który implementuje interfejsy i obsługuje wiele funkcji.

Tematy stanowią podstawę różnych tematów dostępnych w bibliotece, a istnieją też inne tematy – ReplaySubject<T>, BehaviorSubject<T> i AsyncSubject<T>. Warto zrozumieć istotne różnice między nimi i jak je wykorzystać, by lepiej wykorzystać bibliotekę.

W tym artykule porównamy Obiekt<T> i jego rodzeństwo, próbując zilustrować różnice w ich zachowaniach.

Temat<T>

Jak wspomniano wcześniej, Subject<T> stanowi podstawę dostępnych motywów, zapewniając łatwy sposób korzystania z biblioteki bez konieczności samodzielnej implementacji interfejsów IObservable<T> i IObserver<T>. Poniżej przedstawiono prostą demonstrację typu motywu.

W powyższym kodzie stworzyliśmy <T>instancję Subject, a ponieważ implementuje<T> IObserver i IObserverable<T>, używamy tej samej instancji do subskrypcji i publikowania wartości do IObserver. Kolejną ważną kwestią jest sposób, w jaki używamy przeciążenia metody Subscribe do przyjmowania akcji jako wejścia. Będzie to wykonywane dla każdej opublikowanej wartości, w tym przypadku drukując numer na konsoli.

Spróbujmy pokazać opublikowane wartości oraz te, które IObserver (w tej akcji<T>) drukuje na konsoli na poniższym obrazku. To pomoże nam łatwo porównać pozostałe rodzeństwo i warianty.



Pierwsza linia oznacza opublikowaną wartość, a druga linia wartość otrzymaną przez IObserver. Dodatkowo dodaliśmy linię wskazującą, w którym momencie obserwator subskrybuje strumień podczas wykonywania. Linia ta jest przedstawiona przez pionową, przerywaną linię.

W powyższym kodzie zauważyliśmy, że obserwator subskrybował strumień danych przed publikacją pierwszej wartości. Obraz pokazuje linię Subscriber umieszczoną przed pierwszym elementem. Jak widać na linii wyjściowej, nie ma to wpływu na wyjście (na ten moment).

Ale co, jeśli obserwator subskrybuje dane dopiero po opublikowaniu niektórych wartości? Czy ma to wpływ na dane otrzymywane przez obserwatorów? Zanim spojrzymy na wynik, najpierw napiszmy ten sam kod.

W powyższym kodzie możemy zauważyć, że obserwator subskrybuje strumień danych dopiero po opublikowaniu dwóch wartości (1 i 2). Jak można się spodziewać, spowoduje to, że obserwatorzy nie otrzymują danych opublikowanych przed wywołaniem metody subskrypcyjnej. Jak pokazano na poniższym rysunku.



A co jeśli chcesz przeczytać wszystkie opublikowane wartości, nawet jeśli obserwator subskrybuje późno? Właśnie tutaj<T> wkracza ReplaySubject.

Temat <T>powtórki

ReplaySubject<T> zapamiętuje wartości i odtwarza je dla późniejszych subskrybentów. To przydatne, by unikać warunków wyścigowych. Zmieńmy poprzedni kod, aby używać ReplaySubject<T> i zobaczmy, jak wpływa to na to, co otrzymuje obserwator.

Jak pokazano w powyższym kodzie, w<T> <T>kodzie prawie nie ma zmian, poza tym, że teraz używamy ReplaySubject zamiast subject. Poniższy diagram ilustruje wpływ na dane otrzymane przez obserwatora.



Jak pokazano na obrazku, wartość buforowana jest teraz odtwarzana abonentowi, nawet jeśli subskrybent subskrybuje później. Oczywiście, ta przydatna funkcja ma swoją cenę. Ta implementacja będzie buforować każdą wartość opublikowaną przez abonenta, co może powodować problemy z pamięcią, gdy ilość danych jest znacznie większa.

Jednak ReplaySubject<T> ma więcej niż jeden sposób rozwiązania tego problemu. Dla tego przykładu przyjrzymy się dwóm przykładom, które wykorzystują ograniczenia rozmiaru i czasu, aby ograniczyć wartość buforowaną.

W pierwszym przypadku użyjemy rozmiaru pamięci podręcznej, aby ograniczyć jej wartość. <T>Konstruktor ReplaySubject zapewnia przeciążenie, które akceptuje liczbę całkowitą reprezentującą rozmiar bufora pamięci podręcznej (maksymalną liczbę elementów). W naszym przykładzie zmieńmy kod tak, aby ograniczył rozmiar pamięci podręcznej do 1.

Zwróć uwagę, jak używamy <T>przeciążenia konstruktora ReplaySubject, aby podać rozmiar pamięci podręcznej jako 1. Ogranicza to buforowanie i zapewnia, że tylko jeden element jest buforowany i zastępowany nowym elementem zaraz po publikacji. Wpływ tej zmiany przedstawiono poniżej.



Innym sposobem ograniczenia buforowania jest ograniczenie czasu przechowywania przedmiotu, innymi słowy, podanie czasu wygaśnięcia dla tego elementu.

Napiszmy kod, który zilustruje ten przykład.

Podobnie jak w poprzednim kodzie, używamy<T> przeciążenia konstruktora ReplaySubject do określenia czasu wygaśnięcia elementów w pamięci podręcznej. Aby udowodnić naszą tezę, wprowadziliśmy opóźnienie między ujawnieniem wartości.

Ponieważ subskrypcja obserwatora trwa pełne 1200 ms, wszelkie elementy przekraczające 1000 ms zostaną usunięte z pamięci podręcznej. W tym przykładzie spowoduje to usunięcie wartości 1 z pamięci podręcznej i nie zostanie ona odtwarzana przez spóźnionych subskrybentów. Jak pokazano na poniższym rysunku.



Są <T>też inne przeciążenia dla ReplaySubject, które zapewniają większą elastyczność i precyzyjnie dopracowują wartości buforowane, ale na przykład zostawimy dwa już omówione powyżej.

BehaviourSubject<T>

BehaviourSubject <T>jest bardzo podobny do ReplaySubject<T>, ponieważ pomaga w cache. Ale jest istotna różnica. BehaviourSubject<T> buforuje tylko ostatnią opublikowaną wartość. Zanim przejdziemy dalej, napiszmy trochę kodu.

Jeśli BehaviorSubject<T> zapamiętuje tylko jedną wartość (która jest ostatnio znana), czym różni się od ReplaySubject o rozmiarze 1<T>? Poniższy diagram wyraźnie odzwierciedla sytuację powyższego kodu.



Jednak nie jest to do końca prawda. Są tu dwie ważne różnice, które należy zrozumieć. Pierwszym jest obecność niewypłacalności. Należy zauważyć, że w powyższym kodzie <T>podajemy wartość 0 jako domyślną wartość w konstruktorze BehaviourSubject. Jeśli w pamięci podręcznej nie istnieje żadna wartość (innymi słowy, nie opublikowano żadnych danych przed subskrypcją obserwatora), wartość domyślna zostanie zwrócona. To różni się od ReplaySubject, który ma rozmiar 1 <T>i nie ma żadnej wartości. Poniższy kod oraz wizualna reprezentacja sekwencji demonstrują to zachowanie.



Drugą różnicą jest zachowanie BehaviorSubject<T> i ReplaySubject<T> podczas subskrypcji ukończonej sekwencji. Po subskrypcji po zakończeniu BehaviorSubject <T> nie będzie miał żadnej wartości, co pokazano w poniższym kodzie.

Subskrybatelom gwarantowane są żadne wartości, ponieważ subskrypcje pojawiają się po ich zakończeniu.



Jednak <T>tak jest w przypadku ReplaySubject. Nie ma gwarancji, że obserwator nie otrzyma żadnych wartości, jak pokazano w poniższym kodzie.

Jak pokazano w powyższym kodzie, pamięć podręczna ma rozmiar 1 i nawet jeśli subskrypcja zostanie wywołana po zakończeniu połączenia, pamięć podręczna pozostanie (do czasu spełnienia warunku wygaśnięcia), więc w tym przypadku otrzymana zostanie ostatnia opublikowana wartość.



AsyncSubject<T>

AsyncSubject <T>jest ostatnim bratem Subject, którego omówimy w tym artykule<T>, i jest bardzo podobny do poprzednich dwóch (ReplaySubject i BehaviourSubject), ponieważ również buforuje wyniki. Ale znowu jest znacząca różnica. AsyncSubject publikuje ostatnią wartość w pamięci podręcznej tylko wtedy, gdy sekwencja jest oznaczona jako kompletna <T> (buforuje tylko jedną wartość, ostatnią wartość).

Weźmy pod uwagę następujący kod.

To wygeneruje wartość dla obserwatora, że sekwencja jest oznaczona jako ostatnia wartość opublikowana przed ukończeniem – wartość 4. Jak pokazano na poniższym rysunku.



Ale co się stanie, jeśli pominiemy wywołanie, które oznacza sekwencję jako zakończoną? Skomentujmy tę linię i spróbujmy jeszcze raz.

Nie generuje to żadnych danych dla obserwatora, ponieważ AsyncSubject<T> publikuje wyniki dopiero po oznaczeniu sekwencji jako zakończonej.



To istotna różnica, o której każdy użytkownik AsyncSubject <T>powinien pamiętać.

konkluzja

Ten artykuł pokazuje <T>różnice między różnymi rodzeństwem Podmiotu oraz niektóre jego warianty. Często warto być świadomym tych subtelnych różnic, ponieważ jeśli tego nie zauważysz, mogą one wykazywać inne zachowanie, niż się spodziewałeś.

Oryginalny link:Logowanie do linku jest widoczne.





Poprzedni:.NET/C# sprawdza, czy dostępny jest port TCP
Następny:NSIS (1) Stwórz prosty instalator
 Ziemianin| Opublikowano 27.01.2024 12:19:47 |
Subskrypcja tematyczna dla Angular RxJS
https://www.itsvse.com/thread-9209-1-1.html
 Ziemianin| Opublikowano 28.04.2024 11:36:59 |
ASP.NET Core wykorzystuje model pośredni MediatR
https://www.itsvse.com/thread-9272-1-1.html
Zrzeczenie się:
Całe oprogramowanie, materiały programistyczne lub artykuły publikowane przez Code Farmer Network służą wyłącznie celom edukacyjnym i badawczym; Powyższe treści nie mogą być wykorzystywane do celów komercyjnych ani nielegalnych, w przeciwnym razie użytkownicy ponoszą wszelkie konsekwencje. Informacje na tej stronie pochodzą z Internetu, a spory dotyczące praw autorskich nie mają z nią nic wspólnego. Musisz całkowicie usunąć powyższą zawartość z komputera w ciągu 24 godzin od pobrania. Jeśli spodoba Ci się program, wspieraj oryginalne oprogramowanie, kup rejestrację i korzystaj z lepszych, autentycznych usług. W przypadku naruszenia praw prosimy o kontakt mailowy.

Mail To:help@itsvse.com