|
|
Opslået på 27/01/2024 12.17.19
|
|
|
|

.Net Reactive Extension giver udviklere et sæt funktioner til at implementere en reaktiv programmeringsmodel for .Net-udviklere, så hændelseshåndtering bliver enklere og mere udtryksfuld ved hjælp af deklarative handlinger. Selvom de vigtigste hjørnesten i reaktiv skalering er IObserver og IObservable interfaces, behøver du som udvikler ofte ikke selv implementere disse interfaces. Biblioteket understøtter den indbyggede type Subject<T>, som implementerer grænseflader og understøtter mange funktioner.
Temaer danner grundlaget for de forskellige emner, der er tilgængelige i biblioteket, og der er andre temaer – ReplaySubject<T>, BehaviorSubject<T> og AsyncSubject<T>. Det er nyttigt at forstå de væsentlige forskelle mellem dem og hvordan man bruger dem til at udnytte biblioteket bedre.
I denne artikel vil vi sammenligne Subjektet<T> og dets søskende og forsøge at illustrere forskellene i deres adfærd.
Emne<T>
Som nævnt tidligere<T> er Subject grundlaget for de tilgængelige temaer og giver en nem måde at bruge biblioteket på uden selv at skulle implementere IObservable<T>- og IObserver-grænsefladerne<T>. En simpel demonstration af tematypen vises nedenfor.
I koden ovenfor oprettede vi en <T>instans af Subject, og da den implementerer<T> IObserver og IObserverable<T>, bruger vi samme instans til at abonnere og publicere værdien til IObserver. Et andet vigtigt punkt at bemærke her er, hvordan vi bruger overbelastningen fra Subscribe-metoden til at acceptere handlinger som input. Dette gøres for hver offentliggjort værdi, i dette tilfælde ved at printe nummeret til konsollen.
Lad os prøve at vise de offentliggjorte værdier og de værdier, som IObserver (i denne handling<T>) udskriver til konsollen i det følgende billede. Det vil hjælpe os med nemt at sammenligne de resterende søskende og varianter.
Den første linje repræsenterer den offentliggjorte værdi, og den anden linje repræsenterer den værdi, IObserveren har modtaget. Derudover har vi tilføjet en linje, der angiver, hvornår observatøren abonnerer på strømmen under udførelsen. Denne linje er repræsenteret af en lodret stiplet linje.
I koden ovenfor bemærkede vi, at observatøren abonnerede på datastrømmen, før den første værdi blev offentliggjort. Billedet viser Subscriber-linjen placeret før det første element. Som du kan se fra udgangslinjen, har dette ingen effekt på udgangen (på nuværende tidspunkt).
Men hvad hvis observatøren kun abonnerer på dataene, efter at nogle værdier allerede er blevet offentliggjort? Har dette indflydelse på de data, observatører modtager? Før vi ser på outputtet, lad os skrive den samme kode først.
I ovenstående kode kan vi observere, at observatøren kun abonnerer på datastrømmen, efter at to værdier (1 og 2) er offentliggjort. Som man kunne forvente, vil dette medføre, at observatører ikke modtager data, der er offentliggjort, før abonnementsmetoden kaldes. Som vist i figuren nedenfor.
Hvad hvis du vil læse alle offentliggjorte værdier, selvom observatøren abonnerer sent? Her kommer ReplaySubject<T> ind i billedet.
ReplaySubject<T>
ReplaySubject<T> cacher værdier og afspiller dem igen for senere abonnenter. Dette er nyttigt for at undgå løbsforhold. Lad os ændre den tidligere kode til at bruge ReplaySubject<T> og se, hvordan det påvirker, hvad observatøren modtager.
Som vist i koden ovenfor, er der<T> <T>næsten ingen ændring i koden, bortset fra at vi nu bruger ReplaySubject i stedet for subject. Følgende diagram illustrerer virkningen på de data, observatøren modtager.
Som vist på billedet, bliver den cachede værdi nu genafspillet for abonnenten, selvom abonnenten abonnerer senere. Selvfølgelig har denne nyttige funktion en pris. Denne implementering cacher alle værdier, der udgives af abonnenten, hvilket kan forårsage dårlige hukommelsesproblemer, når datamængden er betydeligt større.
Dog har ReplaySubject<T> mere end én måde at løse dette problem på. For eksempelets skyld vil vi se på to eksempler, der bruger størrelses- og tidsbegrænsninger til at begrænse den cachede værdi.
Som det første tilfælde vil vi bruge cachens størrelse til at begrænse cachens værdi. <T>ReplaySubjects konstruktør leverer en overload, som accepterer et heltal, der repræsenterer størrelsen af cachebufferen (maksimalt antal elementer). I vores eksempel ændrer vi koden for at begrænse cache-størrelsen til 1.
Bemærk, hvordan vi bruger <T>ReplaySubjects constructor overload til at angive cachens størrelse som 1. Dette begrænser caching og sikrer, at kun ét element caches og erstattes med et nyt element, så snart det offentliggøres. Ændringens indvirkning vises nedenfor.
En anden måde at begrænse caching på er at begrænse tiden for det cachede element, eller med andre ord, at give en udløbstid for det cachede element.
Lad os skrive kode for at illustrere det eksempel.
Ligesom i den forrige kode bruger vi<T> overload fra ReplaySubject-konstruktøren til at angive udløbstiden for elementer i cachen. For at demonstrere vores sag indførte vi en forsinkelse mellem frigivelsen af værdier.
Da det tager hele 1200 ms, før observatøren abonnerer, vil alle elementer, der overstiger 1000 ms udløbstid, blive fjernet fra cachen. I dette eksempel vil dette medføre, at værdi 1 fjernes fra cachen og ikke vil blive genafspillet for sene abonnenter. Som vist i figuren nedenfor.
Der <T>er andre overbelastninger for ReplaySubject, som giver mere fleksibilitet og finjusterer de cachede værdier, men for eksempel beholder vi de to allerede dækkede eksempler ovenfor.
AdfærdSubjekt<T>
BehaviourSubject <T>minder meget om ReplaySubject<T>, idet det hjælper med at cache-værdier. Men der er en væsentlig forskel. BehaviourSubject<T> cacher kun den sidst publicerede værdi. Før vi går videre med dette, lad os skrive noget kode.
Hvis BehaviorSubject<T> kun cacher en enkelt værdi (som sidst er kendt), hvordan adskiller den sig så fra en ReplaySubject af størrelse 1<T>? Følgende diagram afspejler tydeligt situationen i ovenstående kode.
Dette er dog ikke helt sandt. Der er to vigtige forskelle at forstå her. Den første er tilstedeværelsen af defaults. Bemærk, at vi i koden ovenfor <T>angiver værdien 0 som standard i konstruktøren af BehaviourSubject. Hvis der ikke findes nogen værdi i cachen (eller med andre ord, ingen data blev offentliggjort før observatøren abonnerede), vil standardværdien blive returneret. Dette er anderledes end ReplaySubject, som har en størrelse på 1<T>, som ikke har nogen værdi. Den følgende kode og en visuel repræsentation af sekvensen demonstrerer denne adfærd.
Den anden forskel er, hvordan BehaviorSubject<T> og ReplaySubject<T> opfører sig, når de abonnerer på en færdig sekvens. Når du abonnerer efter afslutningen, vil BehaviorSubject <T> ikke have nogen værdi, som vist i koden nedenfor.
Abonnenter er garanteret ikke at modtage nogen værdi, fordi abonnementer sker efter afslutningen.
Dette <T>er dog tilfældet med ReplaySubject. Der er ingen garanti for, at observatøren ikke modtager nogen værdier, som vist i koden nedenfor.
Som vist i koden ovenfor er cachen 1 i størrelse, og selv hvis abonnementet kaldes efter opkaldet er afsluttet, vil cachen forblive (indtil udløbsbetingelsen er opfyldt), så i dette tilfælde vil den sidst publicerede værdi blive modtaget.
AsynkEmne<T>
AsyncSubject <T>er det sidste søskende til Subject, som vi vil udforske i denne artikel<T>, og det ligner meget de to foregående (ReplaySubject og BehaviourSubject) ved, at det også cacher resultater. Men igen er der en væsentlig forskel. AsyncSubject offentliggør kun den sidst cachede værdi, hvis sekvensen er markeret som komplet <T> (den cacher kun én værdi, den sidste værdi).
Overvej følgende kode.
Dette vil generere en værdi for observatøren, hvor sekvensen markeres som den sidste værdi offentliggjort før afslutningen – værdi 4. Som vist i figuren nedenfor.
Men hvad sker der, hvis vi springer det kald over, der markerer sekvensen som fuldført? Lad os kommentere linjen ud og prøve igen.
Dette genererer ikke nogen data for observatøren, fordi AsyncSubject<T> kun offentliggør resultater, efter at sekvensen er markeret som fuldført.
Dette er en væsentlig forskel, som alle, der bruger AsyncSubject, <T>bør huske på.
konklusion
Denne artikel <T>demonstrerer forskellene mellem de forskellige søskende i Subjektet og nogle af dets variationer. Det er ofte nyttigt at være opmærksom på disse subtile forskelle, da de kan udvise en anden adfærd, end du forventede, hvis du ikke er opmærksom på det.
Originalt link:Hyperlink-login er synlig.
|
Tidligere:.NET/C# tjekker, om der er en TCP-port tilgængeligNæste:NSIS (1) Lav en simpel installatør
|