private bool m_disposed; // Disposed flag detects redundant calls to dispose method #endregion #region [ Constructors ] /// <summary> /// Creates a new <see cref="ConcentratorBase"/>. /// </summary> /// <remarks> /// Concentration will not begin until consumer "Starts" concentrator (i.e., calling <see cref="ConcentratorBase.Start"/> method or setting /// <c><see cref="ConcentratorBase.Enabled"/> = true</c>). /// </remarks> protected ConcentratorBase() { m_usePrecisionTimer = true; m_allowSortsByArrival = true; m_allowPreemptivePublishing = true; m_performTimestampReasonabilityCheck = true; m_processingInterval = -1; m_downsamplingMethod = DownsamplingMethod.LastReceived; m_latestMeasurements = new ImmediateMeasurements(this); m_maximumPublicationTimeout = Timeout.Infinite; // Create a new queue for managing real-time frames m_frameQueue = new FrameQueue(this.CreateNewFrame); // Set minimum timer resolution to one millisecond to improve timer accuracy PrecisionTimer.SetMinimumTimerResolution(1); // Create publication wait handle m_publicationWaitHandle = new AutoResetEvent(false); // Create publication thread - this may be one of the few times when you can // accurately argue that you need high priority thread scheduling... m_publicationThread = new Thread(PublishFrames); m_publicationThread.Priority = ThreadPriority.Highest; m_publicationThread.Start(); // This timer monitors the total number of unpublished samples every 5 seconds. This is a useful statistic // to monitor: if total number of unpublished samples exceed lag time, measurement concentration could // be falling behind. m_monitorTimer = new System.Timers.Timer(); m_monitorTimer.Interval = 5000; m_monitorTimer.AutoReset = true; m_monitorTimer.Elapsed += MonitorUnpublishedSamples; }
/// <summary> /// Releases the unmanaged resources used by the <see cref="ConcentratorBase"/> object and optionally releases the managed resources. /// </summary> /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param> protected virtual void Dispose(bool disposing) { if (!m_disposed) { try { if (disposing) { // Make sure concentrator is stopped Stop(); DetachFromFrameRateTimer(m_framesPerSecond, m_processingInterval); m_publicationThread = null; if (m_publicationWaitHandle != null) { AutoResetEvent publicationWaitHandle = m_publicationWaitHandle; m_publicationWaitHandle = null; publicationWaitHandle.Set(); publicationWaitHandle.Dispose(); } if (m_frameQueue != null) { m_frameQueue.Dispose(); } m_frameQueue = null; if (m_monitorTimer != null) { m_monitorTimer.Elapsed -= MonitorUnpublishedSamples; m_monitorTimer.Dispose(); } m_monitorTimer = null; if (m_latestMeasurements != null) { m_latestMeasurements.Dispose(); } m_latestMeasurements = null; m_lastDiscardedMeasurement = null; // Clear minimum timer resolution. PrecisionTimer.ClearMinimumTimerResolution(1); } } finally { m_disposed = true; // Prevent duplicate dispose. if (Disposed != null) Disposed(this, EventArgs.Empty); } } }