IObservable<T> IObservable<T> IObservable<T> IObservable<T> Interface

定義

定義推入型通知的提供者。Defines a provider for push-based notification.

generic <typename T>
public interface class IObservable
public interface IObservable<out T>
type IObservable<'T> = interface
Public Interface IObservable(Of Out T)

類型參數

T

提供通知資訊的物件。The object that provides notification information.

衍生

範例

下列範例說明觀察者設計模式。The following example illustrates the observer design pattern. 它會定義Location包含緯度和經度資訊的類別。It defines a Location class that contains latitude and longitude information.

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; } }
}
Public Structure Location
   Dim lat, lon As Double

   Public Sub New(ByVal latitude As Double, ByVal longitude As Double)
      Me.lat = latitude
      Me.lon = longitude
   End Sub

   Public ReadOnly Property Latitude As Double
      Get
         Return Me.lat
      End Get
   End Property

   Public ReadOnly Property Longitude As Double
      Get
         Return Me.lon
      End Get
   End Property
End Structure

類別提供了實IObservable<T>作為。 LocationTrackerThe LocationTracker class provides the IObservable<T> implementation. TrackLocation方法會傳遞包含緯度Location和經度資料的可為 null 物件。Its TrackLocation method is passed a nullable Location object that contains the latitude and longitude data. 如果值不null是, 則TrackLocation方法會呼叫每OnNext個觀察者的方法。 LocationIf the Location value is not null, the TrackLocation method calls the OnNext method of each observer.

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();
   }
}
Public Class LocationTracker : Implements IObservable(Of Location)

   Public Sub New()
      observers = New List(Of IObserver(Of Location))
   End Sub

   Private observers As List(Of IObserver(Of Location))

   Public Function Subscribe(ByVal observer As System.IObserver(Of Location)) As System.IDisposable _
                            Implements System.IObservable(Of Location).Subscribe
      If Not observers.Contains(observer) Then
         observers.Add(observer)
      End If
      Return New Unsubscriber(observers, observer)
   End Function

   Private Class Unsubscriber : Implements IDisposable
      Private _observers As List(Of IObserver(Of Location))
      Private _observer As IObserver(Of Location)

      Public Sub New(ByVal observers As List(Of IObserver(Of Location)), ByVal observer As IObserver(Of Location))
         Me._observers = observers
         Me._observer = observer
      End Sub

      Public Sub Dispose() Implements IDisposable.Dispose
         If _observer IsNot Nothing AndAlso _observers.Contains(_observer) Then
            _observers.Remove(_observer)
         End If
      End Sub
   End Class

   Public Sub TrackLocation(ByVal loc As Nullable(Of Location))
      For Each observer In observers
         If Not loc.HasValue Then
            observer.OnError(New LocationUnknownException())
         Else
            observer.OnNext(loc.Value)
         End If
      Next
   End Sub

   Public Sub EndTransmission()
      For Each observer In observers.ToArray()
         If observers.Contains(observer) Then observer.OnCompleted()
      Next
      observers.Clear()
   End Sub
End Class

如果值為null,則 TrackLocation方法會具現化物件,如下列範例所示。LocationUnknownException LocationIf the Location value is null, the TrackLocation method instantiates a LocationUnknownException object, which is shown in the following example. 接著, 它會呼叫每OnError個觀察者的方法LocationUnknownException , 並將物件傳遞給它。It then calls each observer's OnError method and passes it the LocationUnknownException object. 請注意, Exception衍生自, 但不會加入任何新的成員。 LocationUnknownExceptionNote that LocationUnknownException derives from Exception, but does not add any new members.

public class LocationUnknownException : Exception
{
   internal LocationUnknownException() 
   { }
}
Public Class LocationUnknownException : Inherits Exception
   Friend Sub New()
   End Sub
End Class

觀察者會藉由呼叫其TrackLocation IObservable<T>.Subscribe方法 (將觀察者物件的參考指派給私用泛型List<T>物件), 來註冊以接收來自物件的通知。Observers register to receive notifications from a TrackLocation object by calling its IObservable<T>.Subscribe method, which assigns a reference to the observer object to a private generic List<T> object. 方法Unsubscriber會傳回物件, 這是可讓IDisposable觀察者停止接收通知的實作為。The method returns an Unsubscriber object, which is an IDisposable implementation that enables observers to stop receiving notifications. LocationTracker類別也EndTransmission包含方法。The LocationTracker class also includes an EndTransmission method. 當沒有進一步的位置資料可用時, 方法會呼叫每個OnCompleted觀察者的方法, 然後清除觀察者的內部清單。When no further location data is available, the method calls each observer's OnCompleted method and then clears the internal list of observers.

在此範例中, LocationReporter類別會提供IObserver<T>實作為。In this example, the LocationReporter class provides the IObserver<T> implementation. 它會顯示主控台目前位置的相關資訊。It displays information about the current location to the console. 其「函式name 」包含參數, 可LocationReporter讓實例在其字串輸出中識別其本身。Its constructor includes a name parameter, which enables the LocationReporter instance to identify itself in its string output. 它也包含Subscribe方法, 它會包裝對提供者的Subscribe方法的呼叫。It also includes a Subscribe method, which wraps a call to the provider's Subscribe method. 這可讓方法將傳回IDisposable的參考指派給私用變數。This allows the method to assign the returned IDisposable reference to a private variable. 類別也Unsubscribe包含方法,它會IObservable<T>.Subscribe呼叫方法所傳回之物件的方法。IDisposable.Dispose LocationReporterThe LocationReporter class also includes an Unsubscribe method, which calls the IDisposable.Dispose method of the object that is returned by the IObservable<T>.Subscribe method. 下列程式碼會定義LocationReporter類別。The following code defines the LocationReporter class.

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();
   }
}
Public Class LocationReporter : Implements IObserver(Of Location)
   Dim unsubscriber As IDisposable
   Dim instName As String

   Public Sub New(ByVal name As String)
      Me.instName = name
   End Sub

   Public ReadOnly Property Name As String
      Get
         Return instName
      End Get
   End Property

   Public Overridable Sub Subscribe(ByVal provider As IObservable(Of Location))
      If provider Is Nothing Then Exit Sub
      unsubscriber = provider.Subscribe(Me)
   End Sub

   Public Overridable Sub OnCompleted() Implements System.IObserver(Of Location).OnCompleted
      Console.WriteLine("The Location Tracker has completed transmitting data to {0}.", Me.Name)
      Me.Unsubscribe()
   End Sub

   Public Overridable Sub OnError(ByVal e As System.Exception) Implements System.IObserver(Of Location).OnError
      Console.WriteLine("{0}: The location cannot be determined.", Me.Name)
   End Sub

   Public Overridable Sub OnNext(ByVal value As Location) Implements System.IObserver(Of Location).OnNext
      Console.WriteLine("{2}: The current location is {0}, {1}", value.Latitude, value.Longitude, Me.Name)
   End Sub

   Public Overridable Sub Unsubscribe()
      unsubscriber.Dispose()
   End Sub
End Class

然後, 下列程式碼會具現化提供者和觀察者。The following code then instantiates the provider and the observer.

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.
Module Module1
   Dim provider As LocationTracker

   Sub Main()
      ' Define a provider and two observers.
      provider = New LocationTracker()
      Dim reporter1 As New LocationReporter("FixedGPS")
      reporter1.Subscribe(provider)
      Dim reporter2 As 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(Nothing)
      provider.EndTransmission()
   End Sub
End Module
' 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.

備註

IObserver<T>IObservable<T>介面會針對推播通知 (也稱為觀察者設計模式) 提供通用的機制。The IObserver<T> and IObservable<T> interfaces provide a generalized mechanism for push-based notification, also known as the observer design pattern. 介面代表傳送通知的類別 (提供者) IObserver<T> ; 介面代表接收它們的類別 (observer)。 IObservable<T>The IObservable<T> interface represents the class that sends notifications (the provider); the IObserver<T> interface represents the class that receives them (the observer). T表示提供通知資訊的類別。T represents the class that provides the notification information. 在某些以推播為基礎的IObserver<T>通知中T , 實作為和可以代表相同的型別。In some push-based notifications, the IObserver<T> implementation and T can represent the same type.

提供者必須執行單一方法, Subscribe這表示觀察者想要接收以推播為基礎的通知。The provider must implement a single method, Subscribe, that indicates that an observer wants to receive push-based notifications. 方法的呼叫端會傳遞觀察者的實例。Callers to the method pass an instance of the observer. 方法會傳回可IDisposable讓觀察者在提供者停止傳送通知之前, 隨時取消通知的執行。The method returns an IDisposable implementation that enables observers to cancel notifications at any time before the provider has stopped sending them.

在任何指定的時間, 指定的提供者可能會有零個、一個或多個觀察者。At any given time, a given provider may have zero, one, or multiple observers. 提供者會負責儲存觀察者的參考, 並確保它們在傳送通知之前都是有效的。The provider is responsible for storing references to observers and ensuring that they are valid before it sends notifications. IObservable<T>介面不會對觀察者數目或傳送通知的順序做出任何假設。The IObservable<T> interface does not make any assumptions about the number of observers or the order in which notifications are sent.

提供者會藉由呼叫IObserver<T>方法, 將下列三種通知傳送給觀察者:The provider sends the following three kinds of notifications to the observer by calling IObserver<T> methods:

  • 目前的資料。The current data. 提供者可以呼叫IObserver<T>.OnNext方法, 將具有目前資料、已變更資料或新資料的T物件傳遞給觀察者。The provider can call the IObserver<T>.OnNext method to pass the observer a T object that has current data, changed data, or fresh data.

  • 錯誤狀況。An error condition. 提供者可以呼叫IObserver<T>.OnError方法, 以通知觀察者發生某個錯誤狀況。The provider can call the IObserver<T>.OnError method to notify the observer that some error condition has occurred.

  • 沒有任何進一步的資料。No further data. 提供者可以呼叫IObserver<T>.OnCompleted方法, 以通知觀察者其已完成傳送通知。The provider can call the IObserver<T>.OnCompleted method to notify the observer that it has finished sending notifications.

方法

Subscribe(IObserver<T>) Subscribe(IObserver<T>) Subscribe(IObserver<T>) Subscribe(IObserver<T>)

通知提供者有觀察器要接收通知。Notifies the provider that an observer is to receive notifications.

適用於

另請參閱