Publisher/Subscriber

 public interface IPublisher
    {
        void Publish<T>(T data);

        void Subscribe<T>(object subscriber, Action<T> pHandler);

        void Unsubscribe(object subscriber);

        void Unsubscribe<T>(object subscriber, Action<T> pHandler);
    }
public class Publisher : IPublisher
    {
        public Publisher()
        {
        }

        internal List<Handler> _handlers = new List<Handler>();

        internal object _locker = new object();

        public void Publish<T>(T data = default(T))
        {
            List<Handler> handlerList;

            lock (_locker)
            {
                handlerList = new List<Handler>(_handlers.Count);

                var handlersToRemove = new List<Handler>(_handlers.Count);

                foreach (var handler in _handlers)
                {
                    if (!handler.Sender.IsAlive)
                    {
                        handlersToRemove.Add(handler);
                    }
                    else if (handler.Type.GetTypeInfo().IsAssignableFrom(typeof(T).GetTypeInfo()))
                    {
                        handlerList.Add(handler);
                    }
                }

                foreach (var htr in handlersToRemove)
                {
                    _handlers.Remove(htr);
                }
            }

            foreach (var hl in handlerList)
            {
                ((Action<T>)hl.Action)(data);
            }
        }

        public void Subscribe<T>(Action<T> pHandler)
        {
            Subscribe(this, pHandler);
        }

        public void Subscribe<T>(object subscriber, Action<T> pHandler)
        {
            var item = new Handler
            {
                Action = pHandler,
                Sender = new WeakReference(subscriber),
                Type = typeof(T)
            };

            lock (_locker)
            {
                _handlers.Add(item);
            }
        }

        public void Unsubscribe()
        {
            Unsubscribe(this);
        }

        public void Unsubscribe(object subscriber)
        {
            lock (_locker)
            {
                var query = _handlers.Where(a => !a.Sender.IsAlive ||
                                                 a.Sender.Target.Equals(subscriber));

                foreach (var h in query.ToList())
                {
                    _handlers.Remove(h);
                }
            }
        }

        public void Unsubscribe<T>()
        {
            Unsubscribe<T>(this);
        }

        public void Unsubscribe<T>(Action<T> pHandler)
        {
            Unsubscribe(this, pHandler);
        }

        public void Unsubscribe<T>(object subscriber, Action<T> pHandler = null)
        {
            lock (_locker)
            {
                var query = _handlers.Where(a => !a.Sender.IsAlive ||
                                                 a.Sender.Target.Equals(subscriber) && a.Type == typeof(T));

                if (pHandler != null)
                {
                    query = query.Where(a => a.Action.Equals(pHandler));
                }

                foreach (var h in query.ToList())
                {
                    _handlers.Remove(h);
                }
            }
        }

        internal class Handler
        {
            public Delegate Action { get; set; }
            public WeakReference Sender { get; set; }
            public Type Type { get; set; }
        }
    }
原文地址:https://www.cnblogs.com/RR-ghost/p/9766000.html