Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il modello di progettazione dell'osservatore richiede una divisione tra un osservatore, che esegue la registrazione per le notifiche e un provider, che monitora i dati e invia notifiche a uno o più osservatori. Questo articolo illustra come creare un osservatore. Un articolo correlato, Come implementare un provider, illustra come creare un provider.
Creare un osservatore
Per creare un osservatore, implementare l'interfaccia System.IObserver<T> . I passaggi seguenti descrivono ogni membro che è necessario definire.
Definire il tipo di osservatore che implementa l'interfaccia System.IObserver<T> .
Il codice seguente definisce un tipo denominato
TemperatureReporterche è un'implementazione costruita System.IObserver<T> con un argomento di tipo generico diTemperature.namespace TemperatureSample; public sealed class TemperatureReporter : IObserver<Temperature>Namespace Global.TemperatureSample Public NotInheritable Class TemperatureReporter Implements IObserver(Of Temperature)Se l'osservatore deve annullare la sottoscrizione prima che il provider chiami IObserver<T>.OnCompleted, definire una variabile privata per contenere l'oggetto IDisposable restituito da IObservable<T>.Subscribee definire un metodo di sottoscrizione.
La variabile
unsubscriberprivata archivia l'oggetto IDisposable . IlSubscribemetodo chiama il metodo del Subscribe provider e assegna l'oggetto restituito aunsubscriber.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 SubDefinire un
Unsubscribemetodo che consenta all'osservatore di interrompere la ricezione delle notifiche prima che il provider chiami IObserver<T>.OnCompleted.public void Unsubscribe() => _unsubscriber?.Dispose();Public Sub Unsubscribe() _unsubscriber?.Dispose() End SubImplementa i tre metodi definiti da IObserver<T>: IObserver<T>.OnNext, IObserver<T>.OnError e IObserver<T>.OnCompleted.
I OnError metodi e OnCompleted possono essere implementazioni stub. Il metodo OnError non deve gestire il parametro Exception passato come un'eccezione, e OnCompleted può chiamare l'implementazione di IDisposable.Dispose del provider.
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
Esempio completo
Nell'esempio seguente viene illustrato il codice sorgente completo per la TemperatureReporter classe , che fornisce l'implementazione IObserver<T> per un'applicazione di monitoraggio della temperatura.
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