Notiz
Zougrëff op dës Säit erfuerdert Autorisatioun. Dir kënnt probéieren, Iech unzemellen oder Verzeechnesser ze änneren.
Zougrëff op dës Säit erfuerdert Autorisatioun. Dir kënnt probéieren, Verzeechnesser ze änneren.
The observer design pattern requires a division between an observer, which registers for notifications, and a provider, which monitors data and sends notifications to one or more observers. This article discusses how to create an observer. A related article, How to implement a provider, discusses how to create a provider.
Create an observer
To create an observer, implement the System.IObserver<T> interface. The following steps describe each member you need to define.
Define the observer type that implements the System.IObserver<T> interface.
The following code defines a type named
TemperatureReporterthat is a constructed System.IObserver<T> implementation with a generic type argument ofTemperature.namespace TemperatureSample; public sealed class TemperatureReporter : IObserver<Temperature>Namespace Global.TemperatureSample Public NotInheritable Class TemperatureReporter Implements IObserver(Of Temperature)If the observer needs to unsubscribe before the provider calls IObserver<T>.OnCompleted, define a private variable to hold the IDisposable returned by IObservable<T>.Subscribe, and define a subscription method.
The private variable
unsubscriberstores the IDisposable object. TheSubscribemethod calls the provider's Subscribe method and assigns the returned object tounsubscriber.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 SubDefine an
Unsubscribemethod that lets the observer stop receiving notifications before the provider calls IObserver<T>.OnCompleted.public void Unsubscribe() => _unsubscriber?.Dispose();Public Sub Unsubscribe() _unsubscriber?.Dispose() End SubImplement the three methods defined by IObserver<T>: IObserver<T>.OnNext, IObserver<T>.OnError, and IObserver<T>.OnCompleted.
The OnError and OnCompleted methods can be stub implementations. The OnError method shouldn't handle the passed Exception as an exception, and OnCompleted can call the provider's IDisposable.Dispose implementation.
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
Complete example
The following example shows the complete source code for the TemperatureReporter class, which provides the IObserver<T> implementation for a temperature monitoring application.
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