IObserver<T> Antarmuka
Definisi
Penting
Beberapa informasi terkait produk prarilis yang dapat diubah secara signifikan sebelum dirilis. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Menyediakan mekanisme untuk menerima pemberitahuan berbasis push.
generic <typename T>
public interface class IObserver
public interface IObserver<in T>
type IObserver<'T> = interface
Public Interface IObserver(Of In T)
Jenis parameter
- T
Objek yang menyediakan informasi pemberitahuan.
Parameter jenis ini bersifat kontravarian. Artinya, Anda bisa menggunakan jenis yang Anda tentukan atau jenis apa pun yang tidak banyak diturunkan. Untuk informasi lebih lanjut tentang kovariansi dan kontravariansi, lihat Kovariansi dan Kontravariansi dalam Generik.- Turunan
Contoh
Contoh berikut mengilustrasikan pola desain pengamat. Ini mendefinisikan Location kelas yang berisi informasi lintang dan bujur.
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; } }
}
[<Struct>]
type Location =
{ Latitude: double
Longitude: double }
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
Kelas LocationReporter menyediakan IObserver<T> implementasi. Ini menampilkan informasi tentang lokasi saat ini ke konsol. Konstruktornya mencakup name parameter, yang memungkinkan LocationReporter instans mengidentifikasi dirinya sendiri dalam output string-nya. Ini juga termasuk Subscribe metode, yang membungkus panggilan ke metode penyedia Subscribe . Ini memungkinkan metode untuk menetapkan referensi yang dikembalikan IDisposable ke variabel privat. Kelas ini LocationReporter juga menyertakan Unsubscribe metode , yang memanggil IDisposable.Dispose metode objek yang dikembalikan oleh IObservable<T>.Subscribe metode . Kode berikut mendefinisikan LocationReporter kelas .
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();
}
}
open System
type LocationReporter(name) =
let mutable unsubscriber = Unchecked.defaultof<IDisposable>
member _.Name = name
member this.Subscribe(provider: IObservable<Location>) =
if provider <> null then
unsubscriber <- provider.Subscribe this
member _.Unsubscribe() =
unsubscriber.Dispose()
interface IObserver<Location> with
member this.OnCompleted() =
printfn $"The Location Tracker has completed transmitting data to {name}."
this.Unsubscribe()
member _.OnError(_) =
printfn $"{name}: The location cannot be determined."
member _.OnNext(value) =
printfn $"{name}: The current location is {value.Latitude}, {value.Longitude}"
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
Kelas LocationTracker menyediakan IObservable<T> implementasi. Metodenya TrackLocation melewati objek nullable Location yang berisi data lintang dan bujur.
Location Jika nilainya bukan null, TrackLocation metode memanggil OnNext metode setiap pengamat.
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();
}
}
type Unsubscriber(observers: ResizeArray<IObserver<Location>>, observer: IObserver<Location>) =
interface IDisposable with
member _.Dispose() =
if observer <> null && observers.Contains observer then
observers.Remove observer |> ignore
type LocationTracker() =
let observers = ResizeArray<IObserver<Location>>()
interface IObservable<Location> with
member _.Subscribe(observer) =
if observers.Contains observer |> not then
observers.Add observer
new Unsubscriber(observers, observer)
member _.TrackLocation(loc: Nullable<Location>) =
for observer in observers do
if not loc.HasValue then
observer.OnError LocationUnknownException
else
observer.OnNext loc.Value
member _.EndTransmission() =
for observer in observers.ToArray() do
if observers.Contains observer then
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
Jika nilainya Location adalah null, metode membuat TrackLocation instans LocationNotFoundException objek, yang diperlihatkan dalam contoh berikut. Kemudian memanggil metode setiap pengamat OnError dan meneruskannya objek LocationNotFoundException . Perhatikan bahwa LocationNotFoundException berasal dari Exception tetapi tidak menambahkan anggota baru.
public class LocationUnknownException : Exception
{
internal LocationUnknownException()
{ }
}
exception LocationUnknownException
Public Class LocationUnknownException : Inherits Exception
Friend Sub New()
End Sub
End Class
Pengamat mendaftar untuk menerima pemberitahuan dari TrackLocation objek dengan memanggil metodenya IObservable<T>.Subscribe , yang menetapkan referensi ke objek pengamat ke objek generik List<T> privat. Metode mengembalikan Unsubscriber objek, yang merupakan IDisposable implementasi yang memungkinkan pengamat berhenti menerima pemberitahuan. Kelas ini LocationTracker juga menyertakan EndTransmission metode . Ketika tidak ada data lokasi lebih lanjut yang tersedia, metode memanggil metode setiap pengamat OnCompleted dan kemudian menghapus daftar internal pengamat.
Kode berikut kemudian membuat instans penyedia dan pengamat.
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.
open System
// Define a provider and two observers.
let provider = LocationTracker()
let reporter1 = LocationReporter "FixedGPS"
reporter1.Subscribe provider
let reporter2 = LocationReporter "MobileGPS"
reporter2.Subscribe provider
provider.TrackLocation { Latitude = 47.6456; Longitude = -122.1312 }
reporter1.Unsubscribe()
provider.TrackLocation { Latitude = 47.6677; Longitude = -122.1199 }
provider.TrackLocation(Nullable())
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.
Keterangan
Antarmuka IObserver<T> dan IObservable<T> menyediakan mekanisme umum untuk pemberitahuan berbasis push, juga dikenal sebagai pola desain pengamat. Antarmuka IObservable<T> mewakili kelas yang mengirim pemberitahuan (penyedia); IObserver<T> antarmuka mewakili kelas yang menerimanya (pengamat).
T mewakili kelas yang menyediakan informasi pemberitahuan.
Implementasi IObserver<T> mengatur untuk menerima pemberitahuan dari penyedia ( IObservable<T> implementasi) dengan meneruskan instans itu sendiri ke metode penyedia IObservable<T>.Subscribe . Metode ini mengembalikan IDisposable objek yang dapat digunakan untuk berhenti berlangganan pengamat sebelum penyedia selesai mengirim pemberitahuan.
Antarmuka IObserver<T> mendefinisikan tiga metode berikut yang harus diterapkan pengamat:
Metode OnNext ini, yang biasanya dipanggil oleh penyedia untuk menyediakan pengamat dengan data baru atau informasi status.
Metode OnError , yang biasanya dipanggil oleh penyedia untuk menunjukkan bahwa data tidak tersedia, tidak dapat diakses, atau rusak, atau bahwa penyedia telah mengalami beberapa kondisi kesalahan lainnya.
Metode OnCompleted ini, yang biasanya dipanggil oleh penyedia untuk menunjukkan bahwa ia telah selesai mengirim pemberitahuan kepada pengamat.
Metode
| Nama | Deskripsi |
|---|---|
| OnCompleted() |
Memberi tahu pengamat bahwa penyedia telah selesai mengirim pemberitahuan berbasis push. |
| OnError(Exception) |
Memberi tahu pengamat bahwa penyedia telah mengalami kondisi kesalahan. |
| OnNext(T) |
Menyediakan data baru kepada pengamat. |