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