欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#订阅与发布标准实现

程序员文章站 2024-02-01 11:44:52
大概看了下C#官方提供的IObservable接口以及IObserver接口来实现发布和订阅,写的很标准,很有代表性,做下笔记,以后要是项目需要用到发布订阅再基于自己的需求改: public class BaggageInfo { private int flightNo; private stri ......

大概看了下c#官方提供的iobservable接口以及iobserver接口来实现发布和订阅,写的很标准,很有代表性,做下笔记,以后要是项目需要用到发布订阅再基于自己的需求改:

C#订阅与发布标准实现
public class baggageinfo
{
   private int flightno;
   private string origin;
   private int location;

   internal baggageinfo(int flight, string from, int carousel)
   {
      this.flightno = flight;
      this.origin = from;
      this.location = carousel;
   }

   public int flightnumber {
      get { return this.flightno; }
   }

   public string from {
      get { return this.origin; }
   }

   public int carousel {
      get { return this.location; }
   }
}

///
/// 发布者
///
public class baggagehandler : iobservable<baggageinfo>
{
   private list<iobserver<baggageinfo>> observers;
   private list<baggageinfo> flights;

   public baggagehandler()
   {
      observers = new list<iobserver<baggageinfo>>();
      flights = new list<baggageinfo>();
   }

   public idisposable subscribe(iobserver<baggageinfo> observer)
   {
      // check whether observer is already registered. if not, add it
      if (! observers.contains(observer)) {
         observers.add(observer);
         // provide observer with existing data.
         foreach (var item in flights)
            observer.onnext(item);
      }
      return new unsubscriber<baggageinfo>(observers, observer);
   }

   // called to indicate all baggage is now unloaded.
   public void baggagestatus(int flightno)
   {
      baggagestatus(flightno, string.empty, 0);
   }

   public void baggagestatus(int flightno, string from, int carousel)
   {
      var info = new baggageinfo(flightno, from, carousel);

      // carousel is assigned, so add new info object to list.
      if (carousel > 0 && ! flights.contains(info)) {
         flights.add(info);
         foreach (var observer in observers)
            observer.onnext(info);
      }
      else if (carousel == 0) {
         // baggage claim for flight is done
         var flightstoremove = new list<baggageinfo>();
         foreach (var flight in flights) {
            if (info.flightnumber == flight.flightnumber) {
               flightstoremove.add(flight);
               foreach (var observer in observers)
                  observer.onnext(info);
            }
         }
         foreach (var flighttoremove in flightstoremove)
            flights.remove(flighttoremove);

         flightstoremove.clear();
      }
   }

   public void lastbaggageclaimed()
   {
      foreach (var observer in observers)
         observer.oncompleted();

      observers.clear();
   }
}
internal class unsubscriber<baggageinfo> : idisposable
{
   private list<iobserver<baggageinfo>> _observers;
   private iobserver<baggageinfo> _observer;

   internal unsubscriber(list<iobserver<baggageinfo>> observers, iobserver<baggageinfo> observer)
   {
      this._observers = observers;
      this._observer = observer;
   }

   public void dispose() 
   {
      if (_observers.contains(_observer))
         _observers.remove(_observer);
   }
}

///
/// 订阅者
///
public class arrivalsmonitor : iobserver<baggageinfo>
{
   private string name;
   private list<string> flightinfos = new list<string>();
   private idisposable cancellation;
   private string fmt = "{0,-20} {1,5}  {2, 3}";

   public arrivalsmonitor(string name)
   {
      if (string.isnullorempty(name))
         throw new argumentnullexception("the observer must be assigned a name.");

      this.name = name;
   }

   public virtual void subscribe(baggagehandler provider)
   {
      cancellation = provider.subscribe(this);
   }

   public virtual void unsubscribe()
   {
      cancellation.dispose();
      flightinfos.clear();
   }

   public virtual void oncompleted() 
   {
      flightinfos.clear();
   }

   // no implementation needed: method is not called by the baggagehandler class.
   public virtual void onerror(exception e)
   {
      // no implementation.
   }

   // update information.
   public virtual void onnext(baggageinfo info) 
   {
      bool updated = false;

      // flight has unloaded its baggage; remove from the monitor.
      if (info.carousel == 0) {
         var flightstoremove = new list<string>();
         string flightno = string.format("{0,5}", info.flightnumber);
         
         foreach (var flightinfo in flightinfos) {
            if (flightinfo.substring(21, 5).equals(flightno)) {
               flightstoremove.add(flightinfo);
               updated = true;
            }
         }
         foreach (var flighttoremove in flightstoremove)
            flightinfos.remove(flighttoremove);

         flightstoremove.clear();
      }
      else {
         // add flight if it does not exist in the collection.
         string flightinfo = string.format(fmt, info.from, info.flightnumber, info.carousel);
         if (! flightinfos.contains(flightinfo)) {
            flightinfos.add(flightinfo);
            updated = true;
         }
      }
      if (updated) {
         flightinfos.sort();
         console.writeline("arrivals information from {0}", this.name);
         foreach (var flightinfo in flightinfos)
            console.writeline(flightinfo);

         console.writeline();
      }
   }
}
using system;
using system.collections.generic;

public class example
{
    public static void main()
    {
        //发布者
        baggagehandler provider = new baggagehandler();
        // 订阅者
        arrivalsmonitor observer1 = new arrivalsmonitor("baggageclaimmonitor1");
        // 订阅者
        arrivalsmonitor observer2 = new arrivalsmonitor("securityexit");
        // 发布
        provider.baggagestatus(712, "detroit", 3);
        //订阅
        observer1.subscribe(provider);
        
        provider.baggagestatus(712, "kalamazoo", 3);
        provider.baggagestatus(400, "new york-kennedy", 1);
        provider.baggagestatus(712, "detroit", 3);
        observer2.subscribe(provider);
        
        provider.baggagestatus(511, "san francisco", 2);
        provider.baggagestatus(712);
        observer2.unsubscribe();
        
        provider.baggagestatus(400);
        provider.lastbaggageclaimed();
    }
}
view code