Best practices voor waarnemersontwerppatroon
In .NET wordt het ontwerppatroon van de waarnemer geïmplementeerd als een set interfaces. De System.IObservable<T> interface vertegenwoordigt de gegevensprovider, die ook verantwoordelijk is voor het bieden van een IDisposable implementatie waarmee waarnemers zich kunnen afmelden voor meldingen. De System.IObserver<T> interface vertegenwoordigt de waarnemer. In dit onderwerp worden de aanbevolen procedures beschreven die ontwikkelaars moeten volgen bij het implementeren van het ontwerppatroon van de waarnemer met behulp van deze interfaces.
Threading
Normaal gesproken implementeert een provider de IObservable<T>.Subscribe methode door een bepaalde waarnemer toe te voegen aan een abonneelijst die wordt vertegenwoordigd door een verzamelingsobject en wordt de IDisposable.Dispose methode geïmplementeerd door een bepaalde waarnemer uit de lijst met abonnees te verwijderen. Een waarnemer kan deze methoden op elk gewenst moment aanroepen. Omdat het contract van de provider/waarnemer niet aangeeft wie verantwoordelijk is voor het ongedaan maken van IObserver<T>.OnCompleted de callback-methode, kunnen de provider en waarnemer beide proberen hetzelfde lid uit de lijst te verwijderen. Vanwege deze mogelijkheid moeten zowel de als Dispose de Subscribe methoden thread-safe zijn. Dit omvat doorgaans het gebruik van een gelijktijdige verzameling of een vergrendeling. Implementaties die niet thread-safe zijn, moeten expliciet documenteren dat ze niet zijn.
Eventuele aanvullende garanties moeten worden opgegeven in een laag boven op het provider-/waarnemerscontract. Implementeerfuncties moeten duidelijk aangeven wanneer ze aanvullende vereisten opleggen om verwarring van gebruikers over het waarnemerscontract te voorkomen.
Uitzonderingen verwerken
Vanwege de losse koppeling tussen een gegevensprovider en een waarnemer zijn uitzonderingen in het ontwerppatroon van de waarnemer bedoeld om informatief te zijn. Dit is van invloed op de manier waarop providers en waarnemers uitzonderingen verwerken in het ontwerppatroon van de waarnemer.
De provider: de OnError-methode aanroepen
De OnError methode is bedoeld als een informatief bericht voor waarnemers, net als de IObserver<T>.OnNext methode. De OnNext methode is echter ontworpen om een waarnemer te voorzien van actuele of bijgewerkte gegevens, terwijl de OnError methode is ontworpen om aan te geven dat de provider geen geldige gegevens kan leveren.
De provider moet de volgende aanbevolen procedures volgen bij het afhandelen van uitzonderingen en het aanroepen van de OnError methode:
De provider moet zijn eigen uitzonderingen afhandelen als deze specifieke vereisten heeft.
De provider mag niet verwachten of vereisen dat waarnemers uitzonderingen op een bepaalde manier verwerken.
De provider moet de OnError methode aanroepen wanneer deze een uitzondering afhandelt die de mogelijkheid om updates te bieden in gevaar komt. Informatie over dergelijke uitzonderingen kan worden doorgegeven aan de waarnemer. In andere gevallen is het niet nodig om waarnemers op de hoogte te stellen van een uitzondering.
Zodra de provider de OnError of IObserver<T>.OnCompleted methode aanroept, moeten er geen verdere meldingen meer zijn en kan de provider de waarnemers afmelden. De waarnemers kunnen zich echter ook op elk gewenst moment afmelden, inclusief zowel voor als na ontvangst van een OnError melding IObserver<T>.OnCompleted . Het ontwerppatroon van de waarnemer bepaalt niet of de provider of de waarnemer verantwoordelijk is voor het ongedaan maken van de registratie; Daarom is er een mogelijkheid dat beide proberen zich af te melden. Wanneer waarnemers zich afmelden, worden ze meestal verwijderd uit een abonneesverzameling. In een toepassing met één thread moet de IDisposable.Dispose implementatie ervoor zorgen dat een objectverwijzing geldig is en of het object lid is van de verzameling abonnees voordat het wordt verwijderd. In een multithreaded-toepassing moet een thread-safe verzamelingsobject, zoals een System.Collections.Concurrent.BlockingCollection<T> object, worden gebruikt.
De waarnemer: de onError-methode implementeren
Wanneer een waarnemer een foutmelding van een provider ontvangt, moet de waarnemer de uitzondering behandelen als informatief en mag deze niet verplicht zijn om een bepaalde actie te ondernemen.
De waarnemer moet deze aanbevolen procedures volgen bij het reageren op een OnError methodeaanroep van een provider:
De waarnemer mag geen uitzonderingen genereren van de interface-implementaties, zoals OnNext of OnError. Als de waarnemer echter uitzonderingen genereert, moet worden verwacht dat deze uitzonderingen onverwerkt blijven.
Als u de aanroepstack wilt behouden, moet een waarnemer die een Exception object wil genereren dat aan OnError de methode is doorgegeven, de uitzondering verpakken voordat u het genereert. Hiervoor moet een standaard uitzonderingsobject worden gebruikt.
Aanvullende aanbevolen procedures
Als u de registratie van de IObservable<T>.Subscribe methode ongedaan wilt maken, kan dit resulteren in een null-verwijzing. Daarom raden we u aan deze praktijk te vermijden.
Hoewel het mogelijk is om een waarnemer aan meerdere providers te koppelen, is het aanbevolen patroon om een IObserver<T> exemplaar aan slechts één IObservable<T> exemplaar te koppelen.