예제 #1
0
            public static void Run(SchedulerQueue <TimeSpan> queue)
            {
                while (0 < queue.Count)
                {
                    var item = queue.Dequeue();

                    if (item.IsCanceled)
                    {
                        continue;
                    }

                    var wait = item.DueTime - Time;

                    if (wait.Ticks > 0)
                    {
                        ConcurrencyAbstraction.Current.Sleep(wait);
                    }

                    if (false == item.IsCanceled)
                    {
                        item.Invoke();
                    }
                }
            }
예제 #2
0
        /// <summary>
        /// Event loop scheduled on the designated event loop thread. The loop is suspended/resumed using the event
        /// which gets set by calls to Schedule, the next item timer, or calls to Dispose.
        /// </summary>
        private void Run()
        {
            while (true)
            {
                _evt.Wait();

                var ready = default(ScheduledItem <TimeSpan>[]);

                lock (gate)
                {
                    //
                    // Bug fix that ensures the number of calls to Release never greatly exceeds the number of calls to Wait.
                    // See work item #37: https://rx.codeplex.com/workitem/37
                    //
                    while (_evt.CurrentCount > 0)
                    {
                        _evt.Wait();
                    }

                    //
                    // The event could have been set by a call to Dispose. This takes priority over anything else. We quit the
                    // loop immediately. Subsequent calls to Schedule won't ever create a new thread.
                    //
                    if (disposed)
                    {
                        _evt.Dispose();
                        return;
                    }

                    while (queue.Count > 0 && queue.Peek().DueTime <= stopwatch.Elapsed)
                    {
                        var item = queue.Dequeue();
                        readyList.Enqueue(item);
                    }

                    if (queue.Count > 0)
                    {
                        var next = queue.Peek();
                        if (next != nextItem)
                        {
                            nextItem = next;

                            var due = next.DueTime - stopwatch.Elapsed;
                            Disposable.TrySetSerial(ref nextTimer, ConcurrencyAbstraction.Current.StartTimer(Tick, next, due));
                        }
                    }

                    if (readyList.Count > 0)
                    {
                        ready = readyList.ToArray();
                        readyList.Clear();
                    }
                }

                if (null != ready)
                {
                    foreach (var item in ready)
                    {
                        if (!item.IsCanceled)
                        {
                            item.Invoke();
                        }
                    }
                }

                if (ExitIfEmpty)
                {
                    lock (gate)
                    {
                        if (readyList.Count == 0 && queue.Count == 0)
                        {
                            thread = null;
                            return;
                        }
                    }
                }
            }
        }