示例#1
0
 public void Shutdown()
 {
     lock (monitor)
     {
         toShutdown = true;
         do
         {
             try
             {
                 foreach (var entry in subscribers)
                 {
                     MonitorEx.Pulse(monitor, entry.Value);
                 }
                 if (doneShutdown)
                 {
                     return;               //prevent infinite wait due to lost signal
                 }
                 MonitorEx.Wait(monitor, shutdownCondition);
             }
             catch (ThreadInterruptedException)
             {
                 if (subscribers.Count == 0)
                 {
                     Thread.CurrentThread.Interrupt();
                     break;
                 }
                 throw;
             }
         } while (!doneShutdown);
     }
 }
示例#2
0
        public void SubscribeEvent <T>(Action <T> handler) where T : class
        {
            Subscriber sub;

            lock (monitor)
            {
                List <Subscriber> subs;
                if (subscribers.TryGetValue(typeof(T), out subs))
                {
                    subs.Add((sub = new Subscriber(maxPending)));
                }
                else
                {
                    subs = new List <Subscriber>();
                    subs.Add((sub = new Subscriber(maxPending)));
                    subscribers.Add(typeof(T), subs);
                }
            }

            List <Object> events;

            while ((events = GetEvents(sub, typeof(T))) != null)
            {
                foreach (Object ev in events)
                {
                    try
                    {
                        handler((T)ev);
                    }
                    catch (ThreadInterruptedException)
                    {
                        break; //code below!     |
                    }          //                V
                }
            }

            //retirar subscritor do mapa depois de terem sido processados todos os eventos
            //e tiver sido chamado o shutDown ou houve interrupcao

            lock (monitor)
            {
                RemoveSubscriber(typeof(T), sub);

                if (subscribers.Count == 0)
                {
                    doneShutdown = true;
                    MonitorEx.PulseAll(monitor, shutdownCondition);
                }
            }
        }
示例#3
0
        public List <Object> GetEvents(Subscriber subscriber, Type type)
        {
            lock (monitor)
            {
                List <Object> eventsToProcess;
                do
                {
                    //não existem eventos e foi chamado o shutDown
                    if (subscriber.events.Count == 0 && toShutdown)
                    {
                        return(null);
                    }

                    //foi chamado shutDown mas existem eventos a processar
                    if (toShutdown && subscriber.events.Count != 0)
                    {
                        return(subscriber.RemoveSubscriberEvents());
                    }

                    try
                    {
                        List <Subscriber> list;
                        subscribers.TryGetValue(type, out list);
                        MonitorEx.Wait(monitor, list);
                        if (subscriber.events.Count != 0)
                        {
                            return(subscriber.RemoveSubscriberEvents());
                        }
                    }
                    catch (ThreadInterruptedException)
                    {
                        //thread interrompida mas existem eventos a processar
                        if (subscriber.events.Count != 0)
                        {
                            eventsToProcess = subscriber.RemoveSubscriberEvents();
                            //cancelar na posse do lock
                            Thread.CurrentThread.Interrupt();
                            break;
                        }
                        throw;
                    }
                } while (true);
                return(eventsToProcess);
            }
        }
示例#4
0
        public void PublishEvent <E>(E message) where E : class
        {
            lock (monitor)
            {
                if (toShutdown)
                {
                    throw new InvalidOperationException();
                }

                List <Subscriber> subs;
                if (subscribers.TryGetValue(typeof(E), out subs))
                {
                    foreach (Subscriber s in subs)
                    {
                        s.TryAddEvent(message);
                    }
                    MonitorEx.Pulse(monitor, subs);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
        }