Example #1
0
        /// <summary>
        /// This gives an accurate estimate of DateTime from ticks over shorter intervals, it won't be accurate over really long intervals though
        /// </summary>
        DateTime PerfCounterRawDateTime()
        {
            long result;

            Startwatch.QueryPerformanceCounter(out result);
            return(DateTime.Now.AddSeconds(-result / Stopwatch.Frequency));
        }
        /// <summary>
        /// Create the advancement function which will generate the sequence of timers.
        /// Calling this function will automatically close the entire timer hierarchy.
        /// After calling this function, the modeller will become invalidated
        /// and no other functionality will be available.
        /// </summary>
        /// <para>
        /// The first call to the advancement function will start the timer modelling
        /// hierarchy, and each subsequent call will stop the previously returned timer,
        /// and return the next one. The advancement function will eventually
        /// reach the end of the modelled hierarchy, at which point it will
        /// return the <see cref="TotalTimer" /> on each call. It is up
        /// to the caller to stop the TotalTimer at the appropriate point,
        /// which may either be immediately upon seeing it or
        /// at some final point later in the timer hierarchy.
        /// </para>
        public Func <Startwatch> CreateAdvancementFunction()
        {
            if (_current == null)
            {
                throw new InvalidModellerStateException();
            }
            while (_parents.Count > 1)
            {
                Pop();
            }
            _current = null;

            var enum1 = _tracking.GetEnumerator();

            if (_tracking[0] != BeforeStart)
            {
                throw new InvalidOperationException("Modeller tracking state corrupted");
            }
            enum1.MoveNext();

            var enumerator = AdvancementEnumerable(enum1).GetEnumerator();

            return(() => {
                if (enumerator.MoveNext())
                {
                    return enumerator.Current;
                }
                enumerator.Dispose();
                return TotalTimer;
            });
        }
 StartwatchModeller()
 {
     SetupTimer  = _current = new Startwatch();
     _parents    = new Stack <Startwatch>();
     _tracking   = new List <Startwatch>();
     TotalTimer  = AddNext();
     BeforeStart = PushChild();
     SetupTimer.Stop();
 }
Example #4
0
 /// <summary>
 /// Stop time tracking on the Startwatch, allowing for representation of a time period.
 /// </summary>
 /// <returns>true if the watch was running before the call, false if it was already stopped</returns>
 public bool Stop()
 {
     if (_stopTimestamp.Value == 0)
     {
         Startwatch.QueryPerformanceCounter(out _stopTimestamp.Value);
         return(true);
     }
     return(false);
 }
Example #5
0
 /// <summary>
 /// Internal constructor to allow creation of a stopwatch that uses previous sibling 'end' timestamp as the 'start'
 /// for this watch, and uses the assigned parents 'end' timestamp as the 'end' for this watch.
 /// </summary>
 Startwatch(Startwatch sibling, ISibling fakeParentParameter, Startwatch parent, IParent parent1)
 {
     if (parent == null)
     {
         throw new ArgumentNullException("parent");
     }
     _startTimestamp = sibling._stopTimestamp;
     _stopTimestamp  = parent._stopTimestamp;
 }
Example #6
0
        /// <summary>
        /// Create new scoped event pushing the current one onto the stack. Start / stop times will not
        /// be linked but the other timers on the stack will continue measuring time. The pushed event
        /// will be defined by the provided stopwatch instead of one created by the performance tracker.
        /// The event will be managed in the same way as other events, but some behavior will be dependent
        /// on the state of the provided stopwatch.
        /// </summary>
        public IUnstoppablePerformanceEvent PushCustomEvent(Startwatch watch)
        {
            if (_current == _beforeFirstEvent)
            {
                NextEvent();
            }

            _hierarchy.Push(_current);
            return(_current = new PerformanceEvent(watch));
        }
        /// <summary>
        /// Create a new timer that is sequential to the previous one.
        /// A call to next is required for each call of this function (to stop the timer).
        /// </summary>
        public Startwatch AddNext()
        {
            if (_current == null)
            {
                throw new InvalidModellerStateException();
            }
            var result = _current = _current.CreateSibling();

            _tracking.Add(result);
            return(result);
        }
        /// <summary>
        /// Create a new timer which is the last child of a parent.
        /// A call to next <b>is not</b> required for each call to this function.
        /// The timer created by this function will never be returned by the advancement function.
        /// </summary>
        public Startwatch PopNext()
        {
            if (_current == null)
            {
                throw new InvalidModellerStateException();
            }
            var result = _current = _current.CreateLastSibling(_parents.Peek());

            // since it's the last sibling automatically pop the scope back to the parent
            Pop();
            return(result);
        }
        /// <summary>
        /// Create a new timer which is the first child of the parent.
        /// A call to next is required for each call to this function (to stop the timer).
        /// </summary>
        public Startwatch PushChild()
        {
            if (_current == null)
            {
                throw new InvalidModellerStateException();
            }
            _parents.Push(_current);
            var result = _current = _current.CreateChild();

            _tracking[_tracking.Count - 1] = result; // overwrite parent in _tracking
            return(result);
        }
Example #10
0
 /// <summary>
 /// Initialize new Startwatch from System.Diagnostics.Stopwatch,
 /// if the System.Diagnostics.Stopwatch is actively running then the Startwatch will be running and have the same initial duration
 /// if the System.Diagnostics.Stopwatch is stopped then the Startwatch will be stopped
 /// the Startwatch will not be synchronized to the System.Diagnostics.Stopwatch in any way after it is created
 /// </summary>
 public static Startwatch FromStopwatch(Stopwatch watch)
 {
     if (watch.IsRunning)
     {
         long result;
         Startwatch.QueryPerformanceCounter(out result);
         return(new Startwatch(result - watch.ElapsedTicks));
     }
     else
     {
         return(new Startwatch(0, watch.ElapsedTicks));
     }
 }
        /// <summary>
        /// This implements all the confusing logic about stopping the timers at the right times
        /// </summary>
        IEnumerable <Startwatch> AdvancementEnumerable(IEnumerator <Startwatch> enumerator)
        {
            Startwatch prev = BeforeStart;

            while (enumerator.MoveNext())
            {
                // don't stop the timer if it's stop event is linked to the next one
                prev.Stop();
                yield return(prev = enumerator.Current);
            }

            if (prev != null)
            {
                prev.Stop();
            }
            enumerator.Dispose();
        }
        /// <summary>
        /// Goes up the hierarchy of timers to the parent without creating an explicit timer.
        /// A call to next <b>is not</b> required after calling this function because
        /// no timer is created.
        /// </summary>
        public StartwatchModeller Pop()
        {
            if (_current == null)
            {
                throw new InvalidModellerStateException();
            }
            // don't allow user to go outside the 'total'
            if (_parents.Peek() == TotalTimer)
            {
                return(this);
            }

            var result = _current = _parents.Pop();

            _tracking.Add(result);
            return(this);
        }
Example #13
0
        public PerformanceEventTracker()
        {
            var setupWatch = new Startwatch();

            _setupEvent = new PerformanceEvent(setupWatch);

            var realTotalWatch = setupWatch.CreateSibling();

            _realTotalEvent = new PerformanceEvent(realTotalWatch);

            var beforeFirstWatch = realTotalWatch.CreateChild();

            _beforeFirstEvent = new PerformanceEvent(beforeFirstWatch);

            _current   = _beforeFirstEvent;
            _hierarchy = new Stack <PerformanceEvent>();
            _hierarchy.Push(_realTotalEvent);
            _setupEvent.EventCompleted();
        }
Example #14
0
 /// <summary>
 /// internal constructor that allows creation of a child stopwatch from parent
 /// </summary>
 Startwatch(Startwatch parent, IParent fakeParentParameter)
 {
     _startTimestamp = parent._startTimestamp;
     _stopTimestamp  = new RefTimestamp();
 }
Example #15
0
 /// <summary>
 /// internal constructor that allows creation of a sibling stopwatch from older sibling
 /// </summary>
 Startwatch(Startwatch sibling, ISibling fakeParentParameter)
 {
     _startTimestamp = sibling._stopTimestamp;
     _stopTimestamp  = new RefTimestamp();
 }
Example #16
0
 /// <summary>
 /// Represents an Startwatch that is a sibling, but also shares the end event of the provided parent. This
 /// is a somewhat less common event but can be useful when used correctly and in certain circumstances
 /// </summary>
 public Startwatch CreateLastSibling(Startwatch parent)
 {
     return(new Startwatch(this, (ISibling)null, parent, (IParent)null));
 }
 internal PerformanceEvent(Startwatch watch)
 {
     _watch     = watch;
     _behaviors = new List <Action <IUnstoppablePerformanceEvent> >();
 }
Example #18
0
 internal DisposableController(Startwatch controlled)
 {
     Controlled = controlled;
 }
Example #19
0
 /// <summary>
 /// Creates a scoped event that is defined by the provided stopwatch. The event will be managed
 /// in the same way as other performance events, but some behavior is going to be
 /// dependent on the state of the provided stopwatch.
 /// If the previous event was not stopped prior to calling NewEvent(), the previous event
 /// will be stopped automatically.
 /// </summary>
 public IUnstoppablePerformanceEvent AddCustomEvent(Startwatch watch)
 {
     _current.EventCompleted();
     return(_current = new PerformanceEvent(watch));
 }
Example #20
0
 /// <summary>
 /// Create a started stopwatch
 /// </summary>
 public Startwatch()
 {
     _stopTimestamp  = new RefTimestamp();
     _startTimestamp = new RefTimestamp();
     Startwatch.QueryPerformanceCounter(out _startTimestamp.Value);
 }