NetMQ.Poller.PollWhile C# (CSharp) Метод

PollWhile() приватный Метод

Poll as long as the given Func evaluates to true.
This poller must not have already been disposed. This poller must not have already been started.
private PollWhile ( [ condition ) : void
condition [ a Func that returns a boolean value, to evaluate on each poll-iteration to decide when to exit the loop
Результат void
        private void PollWhile([NotNull, InstantHandle] Func<bool> condition)
        {
            if (m_disposed)
            {
                throw new ObjectDisposedException("Poller is disposed");
            }

            if (m_switch.Status)
            {
                throw new InvalidOperationException("Poller is started");
            }

            if (Thread.CurrentThread.Name == null)
                Thread.CurrentThread.Name = "NetMQPollerThread";

            m_switch.SwitchOn();
            try
            {
                // the sockets may have been created in another thread, to make sure we can fully use them we do full memory barrier
                // at the beginning of the loop
                Thread.MemoryBarrier();

                // Recalculate all timers now
                foreach (var timer in m_timers)
                {
                    if (timer.Enable)
                    {
                        timer.When = Clock.NowMs() + timer.Interval;
                    }
                }

                // Do this until the given Func evaluates to false...
                while (condition())
                {
                    if (m_isDirty)
                    {
                        RebuildPollset();
                    }

                    var pollStart = Clock.NowMs();
                    var timeout = TicklessTimer();

                    var isItemsAvailable = false;

                    if (m_pollSize > 0)
                    {
                        isItemsAvailable = m_selector.Select(m_pollset, m_pollSize, timeout);
                    }
                    else
                    {
                        // Don't pass anything less than 0 to sleep or risk an out of range exception or worse - infinity. Do not sleep on 0 from orginal code.
                        if (timeout > 0)
                        {
                            //TODO: Do we really want to simply sleep and return, doing nothing during this interval?
                            //TODO: Should a large value be passed it will sleep for a month literaly.
                            //      Solution should be different, but sleep is more natural here than in selector (timers are not selector concern).
                            Thread.Sleep(timeout);
                        }
                    }

                    // Get the expected end time in case we time out. This looks redundant but, unfortunately,
                    // it happens that Poll takes slightly less than the requested time and 'Clock.NowMs() >= timer.When'
                    // may not true, even if it is supposed to be. In other words, even when Poll times out, it happens
                    // that 'Clock.NowMs() < pollStart + timeout'
                    var expectedPollEnd = !isItemsAvailable ? pollStart + timeout : -1;

                    // that way we make sure we can continue the loop if new timers are added.
                    // timers cannot be removed
                    int timersCount = m_timers.Count;
                    for (int i = 0; i < timersCount; i++)
                    {
                        var timer = m_timers[i];

                        if ((Clock.NowMs() >= timer.When || expectedPollEnd >= timer.When) && timer.When != -1)
                        {
                            timer.InvokeElapsed(this);

                            if (timer.Enable)
                            {
                                timer.When = timer.Interval + Clock.NowMs();
                            }
                        }
                    }

                    for (int itemNbr = 0; itemNbr < m_pollSize; itemNbr++)
                    {
                        SelectItem item = m_pollset[itemNbr];

                        if (item.Socket != null)
                        {
                            NetMQSocket socket = m_pollact[itemNbr];

                            if (item.ResultEvent.HasError())
                            {
                                socket.Errors++;

                                if (socket.Errors > 1)
                                {
                                    RemoveSocket(socket);
                                    item.ResultEvent = PollEvents.None;
                                }
                            }
                            else
                            {
                                socket.Errors = 0;
                            }

                            if (item.ResultEvent != PollEvents.None)
                            {
                                socket.InvokeEvents(this, item.ResultEvent);
                            }
                        }
                        else
                        {
                            if (item.ResultEvent.HasError() || item.ResultEvent.HasIn())
                            {
                                Action<Socket> action;

                                if (m_pollinSockets.TryGetValue(item.FileDescriptor, out action))
                                {
                                    action(item.FileDescriptor);
                                }
                            }
                        }
                    }

                    if (m_zombies.Count > 0)
                    {
                        // Now handle any timer zombies
                        // This is going to be slow if we have many zombies
                        foreach (var netMQTimer in m_zombies)
                        {
                            m_timers.Remove(netMQTimer);
                        }

                        m_zombies.Clear();
                    }
                }
            }
            finally
            {
                try
                {
                    foreach (var socket in m_sockets.ToList())
                    {
                        RemoveSocket(socket);
                    }
                }
                finally
                {
                    m_switch.SwitchOff();
                }
            }
        }