示例#1
0
        private void OnTimer()
        {
            if (_eventSource.IsEnabled())
            {
                DateTime            now;
                TimeSpan            elapsed;
                int                 pollingIntervalInMilliseconds;
                DiagnosticCounter[] counters;
                lock (s_counterGroupLock)
                {
                    now     = DateTime.UtcNow;
                    elapsed = now - _timeStampSinceCollectionStarted;
                    pollingIntervalInMilliseconds = _pollingIntervalInMilliseconds;
                    counters = new DiagnosticCounter[_counters.Count];
                    _counters.CopyTo(counters);
                }

                // MUST keep out of the scope of s_counterGroupLock because this will cause WritePayload
                // callback can be re-entrant to CounterGroup (i.e. it's possible it calls back into EnableTimer()
                // above, since WritePayload callback can contain user code that can invoke EventSource constructor
                // and lead to a deadlock. (See https://github.com/dotnet/runtime/issues/40190 for details)
                foreach (DiagnosticCounter counter in counters)
                {
                    // NOTE: It is still possible for a race condition to occur here. An example is if the session
                    // that subscribed to these batch of counters was disabled and it was immediately enabled in
                    // a different session, some of the counter data that was supposed to be written to the old
                    // session can now "overflow" into the new session.
                    // This problem pre-existed to this change (when we used to hold lock in the call to WritePayload):
                    // the only difference being the old behavior caused the entire batch of counters to be either
                    // written to the old session or the new session. The behavior change is not being treated as a
                    // significant problem to address for now, but we can come back and address it if it turns out to
                    // be an actual issue.
                    counter.WritePayload((float)elapsed.TotalSeconds, pollingIntervalInMilliseconds);
                }

                lock (s_counterGroupLock)
                {
                    _timeStampSinceCollectionStarted = now;
                    TimeSpan delta = now - _nextPollingTimeStamp;
                    delta = _pollingIntervalInMilliseconds > delta.TotalMilliseconds ? TimeSpan.FromMilliseconds(_pollingIntervalInMilliseconds) : delta;
                    if (_pollingIntervalInMilliseconds > 0)
                    {
                        _nextPollingTimeStamp += TimeSpan.FromMilliseconds(_pollingIntervalInMilliseconds * Math.Ceiling(delta.TotalMilliseconds / _pollingIntervalInMilliseconds));
                    }
                }
            }
        }
示例#2
0
 internal void Remove(DiagnosticCounter eventCounter)
 {
     lock (this) // Lock the CounterGroup
         _counters.Remove(eventCounter);
 }
示例#3
0
 internal void Add(DiagnosticCounter eventCounter)
 {
     lock (this) // Lock the CounterGroup
         _counters.Add(eventCounter);
 }