Данная статья переведена с помощью средств машинного перевода. Чтобы просмотреть ее на английском языке, установите флажок Английский. Вы также можете просматривать английский текст во всплывающем окне, наводя указатель мыши на переведенный текст.
Перевод
Английский

Интерфейс IObservable<T>

 

Опубликовано: Октябрь 2016

Определяет поставщика push-уведомлений.

Пространство имен:   System
Сборка:  mscorlib (в mscorlib.dll)

public interface IObservable<out T>

Параметры типа

outT

Объект, предоставляющий сведения об уведомлениях.

ИмяОписание
System_CAPS_pubmethodSubscribe(IObserver<T>)

Уведомляет поставщика о том, что наблюдатель должен получать уведомления.

IObserver<T> И IObservable<T> интерфейсы обеспечивают универсальный механизм для принудительного уведомления, также известного как шаблон разработки наблюдателя. IObservable<T> Интерфейс представляет класс, который отправляет уведомления (поставщик); IObserver<T> интерфейс представляет класс, который получает их (наблюдатель). T Представляет класс, который предоставляет сведения об уведомлении. В некоторых уведомлений на основе принудительной IObserver<T> реализацию и T может представлять тот же тип.

Поставщик должен реализовывать единственный метод, Subscribe, указывает наблюдателя хочет получать push-уведомлений. Вызывающие метод объекты передать экземпляр наблюдателя. Метод возвращает IDisposable реализацию, позволяющую наблюдателям отменить в любое время, прежде чем поставщик был остановлен, отправив уведомления.

В любой момент времени заданный поставщик может иметь ноль, один или несколько наблюдателей. Поставщик отвечает за хранение ссылок на наблюдателей и гарантирует, что они действительны перед отправкой уведомления. IObservable<T> Интерфейс не делать никаких предположений о количестве наблюдателей или порядке отправки уведомлений.

Поставщик отправляет следующие три типа уведомлений наблюдателю путем вызова IObserver<T> методов:

  • Текущие данные. Поставщик может вызвать IObserver<T>.OnNext метод для передачи наблюдателю T объект, который содержит текущие данные, измененными данными или свежими данными.

  • Условие ошибки. Поставщик может вызвать IObserver<T>.OnError метод для уведомления наблюдателя возникшей ошибки.

  • Нет дополнительных данных. Поставщик может вызвать IObserver<T>.OnCompleted метод для уведомления наблюдателя о завершении отправки уведомлений.

В следующем примере шаблон разработки наблюдателя. Он определяет Location класс, содержащий данные широты и долготы.

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; } }
}

LocationTracker Класс предоставляет IObservable<T> реализации. Его TrackLocation методу передается допускающее Location объект, содержащий данные широты и долготы. Если Location значение не null, TrackLocation вызовы метода OnNext метод каждого наблюдателя.

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();
   }
}

Если Location значение null, TrackLocation метод создает LocationUnknownException объекта, как показано в следующем примере. Затем он вызывает каждого наблюдателя OnError метод и передает его LocationUnknownException объекта. Обратите внимание, что LocationUnknownException является производным от Exception, но не добавляет никакие новые члены.

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

Наблюдатели регистрируются для получения уведомлений от TrackLocation вызывая его IObservable<T>.Subscribe метод, который присваивает ссылку на объект наблюдателя закрытый универсальный List<T> объекта. Метод возвращает Unsubscriber объект, являющийся IDisposable реализацию, позволяющую наблюдателям прекратить получение уведомлений. LocationTracker Класс также включает EndTransmission метод. При дальнейших расположение данные недоступны, этот метод вызывает каждого наблюдателя OnCompleted метода, а затем очищает внутренний список наблюдателей.

В этом примере LocationReporter класс предоставляет IObserver<T> реализации. Он отображает сведения о текущем расположении на консоль. Его конструктор включает name параметр, позволяющий LocationReporter экземпляра для идентификации в выводимой строке. Он также включает Subscribe метод, который служит оболочкой вызова к поставщику Subscribe метод. Это позволяет методу для назначения возвращенного IDisposable ссылку в закрытой переменной. LocationReporter Класс также включает Unsubscribe метод, который вызывает IDisposable.Dispose метода объекта, возвращенного IObservable<T>.Subscribe метод. Следующий код определяет LocationReporter класса.

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();
   }
}

Следующий код создает экземпляр поставщика и наблюдателя.

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.

Универсальная платформа Windows
Доступно с 8
.NET Framework
Доступно с 4.0
Переносимая библиотека классов
Поддерживается в: переносимые платформы .NET
Windows Phone Silverlight
Доступно с 7.0
Windows Phone
Доступно с 8.1
Вернуться в начало
Показ: