zoukankan      html  css  js  c++  java
  • C# 通知机制 IObserver<T> 和 IObservable<T>

        class Program
        {
            public static void Main()
            {
                // 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();
    
                Console.ReadLine();
    
                // 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.
            }
        }
        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 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 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 LocationUnknownException : Exception
        {
            internal LocationUnknownException()
            { }
        }
  • 相关阅读:
    E百科 | 第2期 扒一扒能加速互联网的QUIC协议
    阿里的 RocketMQ 如何让双十一峰值之下 0 故障?
    阿里巴巴开源容器镜像加速技术
    Fluid — 云原生环境下的高效“数据物流系统”
    一站式云原生智能告警运维平台——SLS新版告警发布!
    重磅官宣:Nacos2.0 发布,性能提升 10 倍
    阿里云高级技术专家周哲:阿里云边缘云原生应用实践
    互联网泛娱乐直播安全的解决之道
    货运物流移动端解决方案:为货运物流行业打造高性能、高粘性的“双端”触点
    SpringMVC(十四) RequestMapping ModelAndView
  • 原文地址:https://www.cnblogs.com/kikyoqiang/p/10208783.html
Copyright © 2011-2022 走看看