Procedure: Een waarnemer implementeren
Het ontwerppatroon van de waarnemer vereist een verdeling tussen een waarnemer, die zich registreert voor meldingen en een provider, die gegevens bewaakt en meldingen verzendt naar een of meer waarnemers. In dit onderwerp wordt besproken hoe u een waarnemer maakt. Een gerelateerd onderwerp, Procedure: Een provider implementeren, beschrijft hoe u een provider maakt.
Een waarnemer maken
Definieer de waarnemer, een type waarmee de System.IObserver<T> interface wordt geïmplementeerd. Met de volgende code wordt bijvoorbeeld een type gedefinieerd
TemperatureReporter
dat een geconstrueerde System.IObserver<T> implementatie is met een algemeen typeargument vanTemperature
.public class TemperatureReporter : IObserver<Temperature>
Public Class TemperatureReporter : Implements IObserver(Of Temperature)
Als de waarnemer geen meldingen meer kan ontvangen voordat de provider de implementatie aanroept IObserver<T>.OnCompleted , definieert u een privévariabele die de implementatie die wordt geretourneerd door de IDisposable methode van IObservable<T>.Subscribe de provider. U moet ook een abonnementsmethode definiëren waarmee de methode van Subscribe de provider wordt aangeroepen en het geretourneerde object wordt opgeslagen IDisposable . De volgende code definieert bijvoorbeeld een privévariabele met de naam
unsubscriber
en definieert eenSubscribe
methode die de methode van Subscribe de provider aanroept en het geretourneerde object toewijst aan deunsubscriber
variabele.public class TemperatureReporter : IObserver<Temperature> { private IDisposable unsubscriber; private bool first = true; private Temperature last; public virtual void Subscribe(IObservable<Temperature> provider) { unsubscriber = provider.Subscribe(this); }
Public Class TemperatureReporter : Implements IObserver(Of Temperature) Private unsubscriber As IDisposable Private first As Boolean = True Private last As Temperature Public Overridable Sub Subscribe(ByVal provider As IObservable(Of Temperature)) unsubscriber = provider.Subscribe(Me) End Sub
Definieer een methode waarmee de waarnemer geen meldingen meer kan ontvangen voordat de provider de implementatie aanroept IObserver<T>.OnCompleted , als deze functie vereist is. In het volgende voorbeeld wordt een
Unsubscribe
methode gedefinieerd.public virtual void Unsubscribe() { unsubscriber.Dispose(); }
Public Overridable Sub Unsubscribe() unsubscriber.Dispose() End Sub
Bied implementaties van de drie methoden die zijn gedefinieerd door de IObserver<T> interface: IObserver<T>.OnNext, IObserver<T>.OnErroren IObserver<T>.OnCompleted. Afhankelijk van de provider en de behoeften van de toepassing, kunnen de OnError en OnCompleted methoden stub-implementaties zijn. Houd er rekening mee dat de OnError methode het doorgegeven Exception object niet als uitzondering moet verwerken en dat de OnCompleted methode gratis is om de implementatie van IDisposable.Dispose de provider aan te roepen. In het volgende voorbeeld ziet u de IObserver<T> implementatie van de
TemperatureReporter
klasse.public virtual void OnCompleted() { Console.WriteLine("Additional temperature data will not be transmitted."); } public virtual void OnError(Exception error) { // Do nothing. } public virtual void OnNext(Temperature value) { Console.WriteLine("The temperature is {0}°C at {1:g}", value.Degrees, value.Date); if (first) { last = value; first = false; } else { Console.WriteLine(" Change: {0}° in {1:g}", value.Degrees - last.Degrees, value.Date.ToUniversalTime() - last.Date.ToUniversalTime()); } }
Public Overridable Sub OnCompleted() Implements System.IObserver(Of Temperature).OnCompleted Console.WriteLine("Additional temperature data will not be transmitted.") End Sub Public Overridable Sub OnError(ByVal [error] As System.Exception) Implements System.IObserver(Of Temperature).OnError ' Do nothing. End Sub Public Overridable Sub OnNext(ByVal value As Temperature) Implements System.IObserver(Of Temperature).OnNext Console.WriteLine("The temperature is {0}°C at {1:g}", value.Degrees, value.Date) If first Then last = value first = False Else Console.WriteLine(" Change: {0}° in {1:g}", value.Degrees - last.Degrees, value.Date.ToUniversalTime - last.Date.ToUniversalTime) End If End Sub
Opmerking
Het volgende voorbeeld bevat de volledige broncode voor de TemperatureReporter
klasse, die de IObserver<T> implementatie biedt voor een toepassing voor temperatuurbewaking.
public class TemperatureReporter : IObserver<Temperature>
{
private IDisposable unsubscriber;
private bool first = true;
private Temperature last;
public virtual void Subscribe(IObservable<Temperature> provider)
{
unsubscriber = provider.Subscribe(this);
}
public virtual void Unsubscribe()
{
unsubscriber.Dispose();
}
public virtual void OnCompleted()
{
Console.WriteLine("Additional temperature data will not be transmitted.");
}
public virtual void OnError(Exception error)
{
// Do nothing.
}
public virtual void OnNext(Temperature value)
{
Console.WriteLine("The temperature is {0}°C at {1:g}", value.Degrees, value.Date);
if (first)
{
last = value;
first = false;
}
else
{
Console.WriteLine(" Change: {0}° in {1:g}", value.Degrees - last.Degrees,
value.Date.ToUniversalTime() - last.Date.ToUniversalTime());
}
}
}
Public Class TemperatureReporter : Implements IObserver(Of Temperature)
Private unsubscriber As IDisposable
Private first As Boolean = True
Private last As Temperature
Public Overridable Sub Subscribe(ByVal provider As IObservable(Of Temperature))
unsubscriber = provider.Subscribe(Me)
End Sub
Public Overridable Sub Unsubscribe()
unsubscriber.Dispose()
End Sub
Public Overridable Sub OnCompleted() Implements System.IObserver(Of Temperature).OnCompleted
Console.WriteLine("Additional temperature data will not be transmitted.")
End Sub
Public Overridable Sub OnError(ByVal [error] As System.Exception) Implements System.IObserver(Of Temperature).OnError
' Do nothing.
End Sub
Public Overridable Sub OnNext(ByVal value As Temperature) Implements System.IObserver(Of Temperature).OnNext
Console.WriteLine("The temperature is {0}°C at {1:g}", value.Degrees, value.Date)
If first Then
last = value
first = False
Else
Console.WriteLine(" Change: {0}° in {1:g}", value.Degrees - last.Degrees,
value.Date.ToUniversalTime - last.Date.ToUniversalTime)
End If
End Sub
End Class