Språk
Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Mönstret för observatörsdesign kräver en uppdelning mellan en observatör som registrerar sig för meddelanden och en leverantör som övervakar data och skickar meddelanden till en eller flera observatörer. I den här artikeln beskrivs hur du skapar en observatör. I en relaterad artikel, How to implement a provider , beskrivs hur du skapar en leverantör.
Skapa en övervakare
Om du vill skapa en observatör implementerar du gränssnittet System.IObserver<T>. Följande steg beskriver varje medlem som du behöver definiera.
Definiera den observatörstyp som implementerar System.IObserver<T> gränssnittet.
Följande kod definierar en typ med namnet
TemperatureReportersom är en konstruerad System.IObserver<T> implementering med ett allmänt typargument avTemperature.namespace TemperatureSample; public sealed class TemperatureReporter : IObserver<Temperature>Namespace Global.TemperatureSample Public NotInheritable Class TemperatureReporter Implements IObserver(Of Temperature)Om övervakaren behöver avbryta prenumerationen innan providern anropar IObserver<T>.OnCompleteddefinierar du en privat variabel för att lagra den IDisposable som returneras av IObservable<T>.Subscribeoch definierar en prenumerationsmetod.
Den privata variabeln
unsubscriberlagrar IDisposable-objektet. MetodenSubscribeanropar providerns Subscribe metod och tilldelar det returnerade objektet tillunsubscriber.namespace TemperatureSample; public sealed class TemperatureReporter : IObserver<Temperature> { private IDisposable? _unsubscriber; private Temperature? _last; public void Subscribe(IObservable<Temperature> provider) { ArgumentNullException.ThrowIfNull(provider); _unsubscriber = provider.Subscribe(this); }Namespace Global.TemperatureSample Public NotInheritable Class TemperatureReporter Implements IObserver(Of Temperature) Private _unsubscriber As IDisposable Private _last As Temperature? Public Sub Subscribe(provider As IObservable(Of Temperature)) ArgumentNullException.ThrowIfNull(provider) _unsubscriber = provider.Subscribe(Me) End SubDefiniera en
Unsubscribemetod som låter övervakaren sluta ta emot meddelanden innan providern anropar IObserver<T>.OnCompleted.public void Unsubscribe() => _unsubscriber?.Dispose();Public Sub Unsubscribe() _unsubscriber?.Dispose() End SubImplementera de tre metoder som definieras av IObserver<T>: IObserver<T>.OnNext, IObserver<T>.OnErroroch IObserver<T>.OnCompleted.
Metoderna OnError och OnCompleted kan vara stub-implementeringar. Metoden OnError ska inte hantera det som skickas Exception som ett undantag och OnCompleted kan anropa providerns IDisposable.Dispose implementering.
public void OnCompleted() => Console.WriteLine("Additional temperature data won't be transmitted."); // OnError is informational; observers shouldn't treat it as an exception to handle. public void OnError(Exception error) { } public void OnNext(Temperature value) { Console.WriteLine($"The temperature is {value.Degrees}°C at {value.Date:g}"); if (_last is Temperature previous) { TimeSpan elapsed = value.Date.ToUniversalTime() - previous.Date.ToUniversalTime(); Console.WriteLine($" Change: {value.Degrees - previous.Degrees}° in {elapsed:g}"); } _last = value; }Public Sub OnCompleted() Implements IObserver(Of Temperature).OnCompleted Console.WriteLine("Additional temperature data won't be transmitted.") End Sub ' OnError is informational; observers shouldn't treat it as an exception to handle. Public Sub OnError(error_ As Exception) Implements IObserver(Of Temperature).OnError End Sub Public Sub OnNext(value As Temperature) Implements IObserver(Of Temperature).OnNext Console.WriteLine($"The temperature is {value.Degrees}°C at {value.Date:g}") If _last.HasValue Then Dim previous = _last.Value Dim elapsed = value.Date.ToUniversalTime() - previous.Date.ToUniversalTime() Console.WriteLine($" Change: {value.Degrees - previous.Degrees}° in {elapsed:g}") End If _last = value End Sub
Fullständigt exempel
I följande exempel visas den fullständiga källkoden TemperatureReporter för klassen, som tillhandahåller implementeringen IObserver<T> för ett temperaturövervakningsprogram.
namespace TemperatureSample;
public sealed class TemperatureReporter : IObserver<Temperature>
{
private IDisposable? _unsubscriber;
private Temperature? _last;
public void Subscribe(IObservable<Temperature> provider)
{
ArgumentNullException.ThrowIfNull(provider);
_unsubscriber = provider.Subscribe(this);
}
public void Unsubscribe() => _unsubscriber?.Dispose();
public void OnCompleted() =>
Console.WriteLine("Additional temperature data won't be transmitted.");
// OnError is informational; observers shouldn't treat it as an exception to handle.
public void OnError(Exception error) { }
public void OnNext(Temperature value)
{
Console.WriteLine($"The temperature is {value.Degrees}°C at {value.Date:g}");
if (_last is Temperature previous)
{
TimeSpan elapsed = value.Date.ToUniversalTime() - previous.Date.ToUniversalTime();
Console.WriteLine($" Change: {value.Degrees - previous.Degrees}° in {elapsed:g}");
}
_last = value;
}
}
Namespace Global.TemperatureSample
Public NotInheritable Class TemperatureReporter
Implements IObserver(Of Temperature)
Private _unsubscriber As IDisposable
Private _last As Temperature?
Public Sub Subscribe(provider As IObservable(Of Temperature))
ArgumentNullException.ThrowIfNull(provider)
_unsubscriber = provider.Subscribe(Me)
End Sub
Public Sub Unsubscribe()
_unsubscriber?.Dispose()
End Sub
Public Sub OnCompleted() Implements IObserver(Of Temperature).OnCompleted
Console.WriteLine("Additional temperature data won't be transmitted.")
End Sub
' OnError is informational; observers shouldn't treat it as an exception to handle.
Public Sub OnError(error_ As Exception) Implements IObserver(Of Temperature).OnError
End Sub
Public Sub OnNext(value As Temperature) Implements IObserver(Of Temperature).OnNext
Console.WriteLine($"The temperature is {value.Degrees}°C at {value.Date:g}")
If _last.HasValue Then
Dim previous = _last.Value
Dim elapsed = value.Date.ToUniversalTime() - previous.Date.ToUniversalTime()
Console.WriteLine($" Change: {value.Degrees - previous.Degrees}° in {elapsed:g}")
End If
_last = value
End Sub
End Class
End Namespace