Esempio n. 1
0
        /// <summary>
        /// Creates a new time model, optionally providing a starting time and increment
        /// </summary>
        /// <param name="increment">The amount of time to increment on each iteration, defaults to one 100 nanosecond tick</param>
        /// <param name="now">The starting time, defaults to zero</param>
        public Time(TimeSpan?increment = null, TimeSpan?now = null) : base()
        {
            this.Name = "TimeThread";
            Increment = increment.HasValue ? increment.Value : TimeSpan.FromTicks(1);
            Now       = now.HasValue ? now.Value : TimeSpan.Zero;
            InvokeNextCycle(() => current = this);

            EndOfCycle.SubscribeForLifetime(() => Now = Now.Add(Increment), this);

            this.OnDisposed(() =>
            {
                foreach (var func in Functions)
                {
                    func.Lifetime.TryDispose();
                }
            });
        }
Esempio n. 2
0
    private void Loop()
    {
        try
        {
            stopRequested = false;
            Cycle         = -1;
            LoopStarted.Fire();
            List <SynchronizedEvent> todoOnThisCycle = new List <SynchronizedEvent>();
            while (stopRequested == false)
            {
                if (Cycle == long.MaxValue)
                {
                    Cycle = 0;
                }
                else
                {
                    Cycle++;
                }

                try
                {
                    StartOfCycle.Fire();
                }
                catch (Exception ex)
                {
                    var handling = HandleWorkItemException(ex, null);
                    if (handling == EventLoopExceptionHandling.Throw)
                    {
                        throw;
                    }
                    else if (handling == EventLoopExceptionHandling.Stop)
                    {
                        return;
                    }
                    else if (handling == EventLoopExceptionHandling.Swallow)
                    {
                        // swallow
                    }
                }


                lock (workQueue)
                {
                    while (workQueue.Count > 0)
                    {
                        var workItem = workQueue[0];
                        workQueue.RemoveAt(0);
                        todoOnThisCycle.Add(workItem);
                    }
                }

                for (var i = 0; i < pendingWorkItems.Count; i++)
                {
                    if (pendingWorkItems[i].IsFinished && pendingWorkItems[i].IsFailed)
                    {
                        var handling = HandleWorkItemException(pendingWorkItems[i].Exception, pendingWorkItems[i]);
                        if (handling == EventLoopExceptionHandling.Throw)
                        {
                            ExceptionDispatchInfo.Capture(pendingWorkItems[i].Exception).Throw();
                        }
                        else if (handling == EventLoopExceptionHandling.Stop)
                        {
                            return;
                        }
                        else if (handling == EventLoopExceptionHandling.Swallow)
                        {
                            // swallow
                        }

                        var wi = pendingWorkItems[i];
                        pendingWorkItems.RemoveAt(i--);
                        pool.Return(wi);
                        if (stopRequested)
                        {
                            return;
                        }
                    }
                    else if (pendingWorkItems[i].IsFinished)
                    {
                        var wi = pendingWorkItems[i];
                        pendingWorkItems.RemoveAt(i--);
                        pool.Return(wi);
                        if (stopRequested)
                        {
                            return;
                        }
                    }
                }

                foreach (var workItem in todoOnThisCycle)
                {
                    try
                    {
                        workItem.Run();
                        if (workItem.IsFinished == false)
                        {
                            pendingWorkItems.Add(workItem);
                        }
                        else if (workItem.Exception != null)
                        {
                            throw new AggregateException(workItem.Exception);
                        }
                        else
                        {
                            pool.Return(workItem);
                            if (stopRequested)
                            {
                                return;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        var handling = HandleWorkItemException(ex, workItem);
                        if (handling == EventLoopExceptionHandling.Throw)
                        {
                            throw;
                        }
                        else if (handling == EventLoopExceptionHandling.Stop)
                        {
                            return;
                        }
                        else if (handling == EventLoopExceptionHandling.Swallow)
                        {
                            // swallow
                        }
                    }
                }

                todoOnThisCycle.Clear();

                try
                {
                    EndOfCycle.Fire();
                }
                catch (Exception ex)
                {
                    var handling = HandleWorkItemException(ex, null);
                    if (handling == EventLoopExceptionHandling.Throw)
                    {
                        throw;
                    }
                    else if (handling == EventLoopExceptionHandling.Stop)
                    {
                        return;
                    }
                    else if (handling == EventLoopExceptionHandling.Swallow)
                    {
                        // swallow
                    }
                }
            }
        }
        finally
        {
            IsDrainingOrDrained = true;
            LoopStopped.Fire();
            SynchronizationContext.SetSynchronizationContext(null);
        }
    }