Linguagem
Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
O padrão de design do observador requer uma divisão entre um observador, que se registra para notificações, e um provedor, que monitora dados e envia notificações para um ou mais observadores. Este artigo discute como criar um observador. Um artigo relacionado, Como implementar um fornecedor, discute como criar um fornecedor.
Criar um observador
Para criar um observador, implemente a System.IObserver<T> interface. Os passos seguintes descrevem cada membro que precisa de definir.
Defina o tipo de observador que implementa a System.IObserver<T> interface.
O código seguinte define um tipo chamado
TemperatureReporter, que é uma implementação concretizada de System.IObserver<T> com um argumento de tipo genérico deTemperature.namespace TemperatureSample; public sealed class TemperatureReporter : IObserver<Temperature>Namespace Global.TemperatureSample Public NotInheritable Class TemperatureReporter Implements IObserver(Of Temperature)Se o observador precisar de cancelar a subscrição antes de o fornecedor chamar IObserver<T>.OnCompleted, defina uma variável privada para conter o IDisposable devolvido por IObservable<T>.Subscribe e defina um método de subscrição.
A variável
unsubscriberprivada armazena o IDisposable objeto. OSubscribemétodo chama o método do Subscribe fornecedor e atribui o objeto devolvido 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 SubDefina um
Unsubscribemétodo que permita ao observador parar de receber notificações antes de o fornecedor chamar IObserver<T>.OnCompleted.public void Unsubscribe() => _unsubscriber?.Dispose();Public Sub Unsubscribe() _unsubscriber?.Dispose() End SubImplemente os três métodos definidos por IObserver<T>: IObserver<T>.OnNext, IObserver<T>.OnError, e IObserver<T>.OnCompleted.
Os OnError métodos e OnCompleted podem ser implementações stub. O método OnError não deve tratar o Exception passado como uma exceção, e OnCompleted pode chamar a implementação de IDisposable.Dispose do fornecedor.
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
Exemplo completo
O exemplo seguinte mostra o código-fonte completo da TemperatureReporter classe, que fornece a IObserver<T> implementação para uma aplicação de monitorização de 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