/// <summary>
        /// Tries to add the specified event to the storage.
        /// The storage may refuse to store certain events
        /// (e.g. multiple <see cref="ShuttingDownEvent"/>s).
        /// </summary>
        /// <param name="evnt">The event to enqueue.</param>
        /// <returns><c>true</c> if the event was added to the storage; otherwise, <c>false</c>.</returns>
        public bool TryPush(EventBase evnt)
        {
            if (evnt.NullReference())
            {
                throw Exc.Null(nameof(evnt));
            }

            lock (this.syncLock)
            {
                this.events.Add(evnt);
                return(true);
            }
        }
Example #2
0
        /// <summary>
        /// Finds applicable subscribers, and has them handle the specified event, on the current thread.
        /// </summary>
        /// <param name="evnt">The event to handle.</param>
        /// <param name="exceptions">Stores exceptions throws by event handlers.</param>
        protected internal void Handle(EventBase evnt, List <Exception> exceptions)
        {
            if (evnt.NullReference())
            {
                throw Exc.Null(nameof(evnt));
            }

            if (exceptions.NullReference())
            {
                throw Exc.Null(nameof(exceptions));
            }

            lock (this.syncLock)
            {
                var eventTypeInfo = evnt.GetType().GetTypeInfo();
                for (int i = 0; i < this.subscribers.Count;)
                {
                    var wrapper = this.subscribers[i];
                    if (EventBase.CanHandle(wrapper.EventHandlerEventTypeInfo, eventTypeInfo))
                    {
                        bool referenceFound = true;
                        try
                        {
                            wrapper.Handle(evnt, out referenceFound);
                        }
                        catch (Exception ex)
                        {
                            exceptions.Add(ex);
                        }

                        if (referenceFound)
                        {
                            // event handled: continue
                            ++i;
                        }
                        else
                        {
                            // GC already collected the event handler: remove wrapper and continue
                            this.subscribers.RemoveAt(i);
                        }
                    }
                    else
                    {
                        // event handler not compatible with event: continue
                        ++i;
                    }
                }
            }
        }
        /// <summary>
        /// Determines whether the specified event reference is stored.
        /// </summary>
        /// <param name="evnt">The event to search for within the storage.</param>
        /// <returns><c>true</c> if the specified event reference was found; otherwise, <c>false</c>.</returns>
        public bool Contains(EventBase evnt)
        {
            if (evnt.NullReference())
            {
                return(false);
            }

            lock (this.syncLock)
            {
                bool found = false;
                foreach (var e in this.events)
                {
                    if (ReferenceEquals(e, evnt))
                    {
                        found = true;
                        break;
                    }
                }
                return(found);
            }
        }