Leggere in inglese

Condividi tramite


IObserver<T> Interfaccia

Definizione

Fornisce un meccanismo per la ricezione di notifiche basate su push.

C#
public interface IObserver<in T>

Parametri di tipo

T

Oggetto che fornisce informazioni di notifica.

Questo parametro di tipo è controvariante, ovvero puoi usare il tipo specificato o qualsiasi tipo meno derivato. Per altre informazioni sulla covarianza e la controvarianza, vedi Covarianza e controvarianza nei generics.
Derivato

Esempio

Nell'esempio seguente viene illustrato il modello di progettazione dell'osservatore. Definisce una Location classe che contiene informazioni sulla latitudine e la longitudine.

C#
public struct Location
{
   double lat, lon;

   public Location(double latitude, double longitude)
   {
      this.lat = latitude;
      this.lon = longitude;
   }

   public double Latitude
   { get { return this.lat; } }

   public double Longitude
   { get { return this.lon; } }
}

La LocationReporter classe fornisce l'implementazione IObserver<T> . Visualizza informazioni sulla posizione corrente nella console. Il costruttore include un name parametro che consente all'istanza di identificarsi nell'output LocationReporter della stringa. Include anche un Subscribe metodo che esegue il wrapping di una chiamata al metodo del Subscribe provider. In questo modo il metodo può assegnare il riferimento restituito IDisposable a una variabile privata. La LocationReporter classe include anche un Unsubscribe metodo che chiama il IDisposable.Dispose metodo dell'oggetto restituito dal IObservable<T>.Subscribe metodo . Il codice seguente definisce la LocationReporter classe .

C#
using System;

public class LocationReporter : IObserver<Location>
{
   private IDisposable unsubscriber;
   private string instName;

   public LocationReporter(string name)
   {
      this.instName = name;
   }

   public string Name
   {  get{ return this.instName; } }

   public virtual void Subscribe(IObservable<Location> provider)
   {
      if (provider != null)
         unsubscriber = provider.Subscribe(this);
   }

   public virtual void OnCompleted()
   {
      Console.WriteLine("The Location Tracker has completed transmitting data to {0}.", this.Name);
      this.Unsubscribe();
   }

   public virtual void OnError(Exception e)
   {
      Console.WriteLine("{0}: The location cannot be determined.", this.Name);
   }

   public virtual void OnNext(Location value)
   {
      Console.WriteLine("{2}: The current location is {0}, {1}", value.Latitude, value.Longitude, this.Name);
   }

   public virtual void Unsubscribe()
   {
      unsubscriber.Dispose();
   }
}

La LocationTracker classe fornisce l'implementazione IObservable<T> . Il metodo TrackLocation viene passato a un oggetto nullable Location che contiene i dati di latitudine e longitudine. Se il Location valore non nullè , il TrackLocation metodo chiama il OnNext metodo di ogni osservatore.

C#
public class LocationTracker : IObservable<Location>
{
   public LocationTracker()
   {
      observers = new List<IObserver<Location>>();
   }

   private List<IObserver<Location>> observers;

   public IDisposable Subscribe(IObserver<Location> observer)
   {
      if (! observers.Contains(observer))
         observers.Add(observer);
      return new Unsubscriber(observers, observer);
   }

   private class Unsubscriber : IDisposable
   {
      private List<IObserver<Location>>_observers;
      private IObserver<Location> _observer;

      public Unsubscriber(List<IObserver<Location>> observers, IObserver<Location> observer)
      {
         this._observers = observers;
         this._observer = observer;
      }

      public void Dispose()
      {
         if (_observer != null && _observers.Contains(_observer))
            _observers.Remove(_observer);
      }
   }

   public void TrackLocation(Nullable<Location> loc)
   {
      foreach (var observer in observers) {
         if (! loc.HasValue)
            observer.OnError(new LocationUnknownException());
         else
            observer.OnNext(loc.Value);
      }
   }

   public void EndTransmission()
   {
      foreach (var observer in observers.ToArray())
         if (observers.Contains(observer))
            observer.OnCompleted();

      observers.Clear();
   }
}

Se il Location valore è null, il metodo crea un'istanza TrackLocation di un LocationNotFoundException oggetto , illustrato nell'esempio seguente. Chiama quindi il metodo di OnError ogni osservatore e lo passa all'oggetto LocationNotFoundException . Si noti che LocationNotFoundException deriva da Exception ma non aggiunge nuovi membri.

C#
public class LocationUnknownException : Exception
{
   internal LocationUnknownException()
   { }
}

Gli osservatori registrano per ricevere notifiche da un TrackLocation oggetto chiamando il relativo IObservable<T>.Subscribe metodo, che assegna un riferimento all'oggetto osservatore a un oggetto generico privato List<T> . Il metodo restituisce un Unsubscriber oggetto , che è un'implementazione IDisposable che consente agli osservatori di interrompere la ricezione delle notifiche. La LocationTracker classe include anche un EndTransmission metodo . Quando non sono disponibili ulteriori dati sulla posizione, il metodo chiama il metodo di OnCompleted ogni osservatore e quindi cancella l'elenco interno di osservatori.

Il codice seguente crea quindi un'istanza del provider e dell'osservatore.

C#
using System;

class Program
{
   static void Main(string[] args)
   {
      // Define a provider and two observers.
      LocationTracker provider = new LocationTracker();
      LocationReporter reporter1 = new LocationReporter("FixedGPS");
      reporter1.Subscribe(provider);
      LocationReporter reporter2 = new LocationReporter("MobileGPS");
      reporter2.Subscribe(provider);

      provider.TrackLocation(new Location(47.6456, -122.1312));
      reporter1.Unsubscribe();
      provider.TrackLocation(new Location(47.6677, -122.1199));
      provider.TrackLocation(null);
      provider.EndTransmission();
   }
}
// The example displays output similar to the following:
//      FixedGPS: The current location is 47.6456, -122.1312
//      MobileGPS: The current location is 47.6456, -122.1312
//      MobileGPS: The current location is 47.6677, -122.1199
//      MobileGPS: The location cannot be determined.
//      The Location Tracker has completed transmitting data to MobileGPS.

Commenti

Le IObserver<T> interfacce e IObservable<T> forniscono un meccanismo generalizzato per la notifica basata su push, noto anche come modello di progettazione osservatore. L'interfaccia IObservable<T> rappresenta la classe che invia notifiche (il provider); l'interfaccia IObserver<T> rappresenta la classe che li riceve (l'osservatore). T rappresenta la classe che fornisce le informazioni di notifica.

Un'implementazione IObserver<T> dispone di ricevere notifiche da un provider (un'implementazione IObservable<T> ) passando un'istanza di se stessa al metodo del IObservable<T>.Subscribe provider. Questo metodo restituisce un IDisposable oggetto che può essere utilizzato per annullare la sottoscrizione dell'osservatore prima che il provider finisca l'invio di notifiche.

L'interfaccia IObserver<T> definisce i tre metodi seguenti che l'osservatore deve implementare:

  • Il OnNext metodo, in genere chiamato dal provider per fornire all'osservatore nuove informazioni sui dati o sullo stato.

  • Il OnError metodo, che viene in genere chiamato dal provider per indicare che i dati non sono disponibili, inaccessibili o danneggiati o che il provider ha riscontrato un'altra condizione di errore.

  • Il OnCompleted metodo, che viene in genere chiamato dal provider per indicare che ha completato l'invio di notifiche agli osservatori.

Metodi

OnCompleted()

Notifica all'osservatore che il provider ha terminato di inviare notifiche basate su push.

OnError(Exception)

Notifica all'osservatore una condizione di errore del provider.

OnNext(T)

Fornisce nuovi dati all'osservatore.

Si applica a

Prodotto Versioni
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7
.NET Framework 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 2.0, 2.1
UWP 10.0

Vedi anche