Пример #1
0
        public IDisposable Subscribe <T>(WeakAction <T> action) where T : class, IMessage
        {
            NotNull(action, "action");

            Type key       = typeof(T);
            var  container = CheckForKey(key);

            _locker.SafeWork(() =>
            {
                if (container.Contains(action))
                {
                    throw new InvalidOperationException("This subscriber has been already subscribed to this event.");
                }

                container.Add(action);
            });

            return(new Disposer(() =>
            {
                HashSet <WeakAction> dump;

                Type[] args = action.GetType().GetGenericArguments();
                if (args != null && args.Length > 0)
                {
                    if (!_lazyDict.Value.TryGetValue(args[0], out dump))
                    {
                        return;
                    }

                    _locker.SafeWork(() => dump.Remove(action));
                    (action).MarkForDeletion();
                }
            }));
        }
Пример #2
0
        public IDisposable Subscribe <T>(ISubscriber <T> subscriber) where T : class, IMessage
        {
            NotNull(subscriber, "subscriber");
            Type key = typeof(T);
            HashSet <WeakReference> container = CheckForKey(key);

            HashSet <IMessage> delayedMsgs;

            if (container.Count == 0 && _lazyDefferMsgs.Value.TryGetValue(key, out delayedMsgs) && delayedMsgs != null)
            {
                Parallel.ForEach(delayedMsgs, item =>
                {
                    if ((subscriber as INotify <T>) != null)
                    {
                        _locker.SafeWork(() => (subscriber as INotify <T>).Notify(item as T));
                    }
                    else
                    if ((subscriber as ISubscriber <T>) != null)
                    {
                        _locker.SafeWork(() => (subscriber as ISubscriber <T>).HandleEvent(item as T));
                    }
                });
            }

            WeakReference weak = new WeakReference(subscriber);

            _locker.SafeWork(() =>
            {
                if (container.Contains(weak))
                {
                    throw new InvalidOperationException("This subscriber has been already subscribed to this event.");
                }

                container.Add(weak);
            });

            return(new Disposer(() =>
            {
                HashSet <WeakReference> dump;
                Type msgType = subscriber.GetType().GetInterfaces().Where(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(ISubscriber <>))
                               .Select(x => x.GetGenericArguments()[0]).FirstOrDefault();
                if (msgType == null || !_lazyDict.Value.TryGetValue(msgType, out dump))
                {
                    return;
                }

                _locker.SafeWork(() => dump.Remove(weak));
            }));
        }