Represents a timer class that will group registered timer event callbacks that operate on the same interval in order to optimize thread pool queuing.

Externally the SharedTimer operations similar to the System.Timers.Timer. Internally the timer pools callbacks with the same Interval into a single timer where each callback is executed on the same thread, per instance of the SharedTimerScheduler.

Any long running callbacks that have a risk of long delays should not use SharedTimer as this will effect the reliability of all of the other SharedTimer instances for a given SharedTimerScheduler.

Наследование: IDisposable
        /// <summary>
        /// Constructs a new instance of the <see cref="InputAdapterBase"/>.
        /// </summary>
        protected InputAdapterBase()
        {
            m_connectionOperation = new LongSynchronizedOperation(AttemptConnectionOperation)
            {
                IsBackground = true
            };

            m_connectionTimer = Common.TimerScheduler.CreateTimer(2000);
            m_connectionTimer.Elapsed += m_connectionTimer_Elapsed;

            m_connectionTimer.AutoReset = false;
            m_connectionTimer.Enabled = false;
        }
        private void StartMeasurementCounter()
        {
            long now = DateTime.UtcNow.Ticks;

            DataSet dataSource;
            DataTable measurementTable;
            IConfigurationFrame configurationFrame;
            int measurementsPerFrame;

            if (!m_receivedConfigFrame)
            {
                // If this is the first time we've received the configuration frame,
                // we'll use it to calculate expected measurements per second for each device
                dataSource = DataSource;

                if ((object)dataSource != null && dataSource.Tables.Contains("ActiveMeasurements"))
                {
                    measurementTable = dataSource.Tables["ActiveMeasurements"];
                    configurationFrame = m_frameParser.ConfigurationFrame;

                    foreach (DeviceStatisticsHelper<ConfigurationCell> statisticsHelper in StatisticsHelpers)
                    {
                        measurementsPerFrame = measurementTable.Select($"SignalReference LIKE '{statisticsHelper.Device.IDLabel}-%' AND SignalType <> 'FLAG' AND SignalType <> 'STAT'").Length;
                        statisticsHelper.ExpectedMeasurementsPerSecond = configurationFrame.FrameRate * measurementsPerFrame;
                        statisticsHelper.Reset(now);
                    }
                }
            }

            if ((object)m_measurementCounter == null)
            {
                // Create the timer if it doesn't already exist
                m_measurementCounter = CommonPhasorServices.TimerScheduler.CreateTimer(1000);
                m_measurementCounter.Elapsed += m_measurementCounter_Elapsed;
            }

            // Start the measurement counter timer
            // to start gathering statistics
            m_measurementCounter.Start();
        }
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="DataGapRecoverer"/> 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)
                    {
                        if ((object)m_dataGapRecoveryCompleted != null)
                        {
                            // Signal any waiting threads
                            m_abnormalTermination = true;
                            m_dataGapRecoveryCompleted.Set();
                            m_dataGapRecoveryCompleted.Dispose();
                        }

                        if ((object)m_dataStreamMonitor != null)
                        {
                            m_dataStreamMonitor.Elapsed -= DataStreamMonitor_Elapsed;
                            m_dataStreamMonitor.Dispose();
                            m_dataStreamMonitor = null;
                        }

                        if ((object)m_dataGapLogProcessor != null)
                        {
                            m_dataGapLogProcessor.Dispose();
                            m_dataGapLogProcessor = null;
                        }

                        if ((object)m_dataGapLog != null)
                        {
                            m_dataGapLog.ProcessException -= Common_ProcessException;
                            m_dataGapLog.Dispose();
                            m_dataGapLog = null;
                        }

                        if ((object)m_temporalSubscription != null)
                        {
                            m_temporalSubscription.StatusMessage -= Common_StatusMessage;
                            m_temporalSubscription.ProcessException -= Common_ProcessException;
                            m_temporalSubscription.ConnectionEstablished -= TemporalSubscription_ConnectionEstablished;
                            m_temporalSubscription.ConnectionTerminated -= TemporalSubscription_ConnectionTerminated;
                            m_temporalSubscription.NewMeasurements -= TemporalSubscription_NewMeasurements;
                            m_temporalSubscription.ProcessingComplete -= TemporalSubscription_ProcessingComplete;
                            m_temporalSubscription.Dispose();
                            m_temporalSubscription = null;
                        }
                    }
                }
                finally
                {
                    m_disposed = true;  // Prevent duplicate dispose.

                    if ((object)Disposed != null)
                        Disposed(this, EventArgs.Empty);
                }
            }
        }
 /// <summary>
 /// Releases the unmanaged resources used by the <see cref="InputAdapterBase"/> 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 override void Dispose(bool disposing)
 {
     if (!m_disposed)
     {
         try
         {
             if (disposing)
             {
                 if (m_connectionTimer != null)
                 {
                     m_connectionTimer.Elapsed -= m_connectionTimer_Elapsed;
                     m_connectionTimer.Dispose();
                 }
                 m_connectionTimer = null;
             }
         }
         finally
         {
             m_disposed = true;          // Prevent duplicate dispose.
             base.Dispose(disposing);    // Call base class Dispose().
         }
     }
 }
        /// <summary>
        /// Constructs a new instance of the <see cref="OutputAdapterBase"/>.
        /// </summary>
        protected OutputAdapterBase()
        {
            m_metadataRefreshOperation = new LongSynchronizedOperation(ExecuteMetadataRefresh)
            {
                IsBackground = true
            };

            m_measurementQueue = ProcessQueue<IMeasurement>.CreateRealTimeQueue(ProcessMeasurements);
            m_measurementQueue.ProcessException += m_measurementQueue_ProcessException;

            m_connectionOperation = new LongSynchronizedOperation(AttemptConnectionOperation)
            {
                IsBackground = true
            };

            m_connectionTimer = Common.TimerScheduler.CreateTimer(2000);
            m_connectionTimer.Elapsed += m_connectionTimer_Elapsed;

            m_connectionTimer.AutoReset = false;
            m_connectionTimer.Enabled = false;

            // We monitor total number of unarchived measurements every 5 seconds - this is a useful statistic to monitor, if
            // total number of unarchived measurements gets very large, measurement archival could be falling behind
            m_monitorTimer = Common.TimerScheduler.CreateTimer(5000);
            m_monitorTimer.Elapsed += m_monitorTimer_Elapsed;

            m_monitorTimer.AutoReset = true;
            m_monitorTimer.Enabled = false;
        }
        /// <summary>
        /// Creates a new <see cref="DataGapRecoverer"/>.
        /// </summary>
        public DataGapRecoverer()
        {
            Log = Logger.CreatePublisher(GetType(), MessageClass.Framework);
            Log.InitialStackMessages = Log.InitialStackMessages.Union("ComponentName", GetType().Name);

            m_dataGapRecoveryCompleted = new ManualResetEventSlim(true);

            m_recoveryStartDelay = DefaultRecoveryStartDelay;
            m_minimumRecoverySpan = DefaultMinimumRecoverySpan;
            m_maximumRecoverySpan = DefaultMaximumRecoverySpan;

            string loggingPath = FilePath.GetDirectoryName(FilePath.GetAbsolutePath(DataSubscriber.DefaultLoggingPath));

            if (Directory.Exists(loggingPath))
                m_loggingPath = loggingPath;

            m_subscriptionInfo = new UnsynchronizedSubscriptionInfo(false);
            m_subscriptionInfo.FilterExpression = DefaultFilterExpression;
            m_subscriptionInfo.ProcessingInterval = DefaultRecoveryProcessingInterval;
            m_subscriptionInfo.UseMillisecondResolution = DefaultUseMillisecondResolution;

            m_dataStreamMonitor = Common.TimerScheduler.CreateTimer((int)(DefaultDataMonitoringInterval * 1000.0D));
            m_dataStreamMonitor.Elapsed += DataStreamMonitor_Elapsed;
            m_dataStreamMonitor.AutoReset = true;
            m_dataStreamMonitor.Enabled = false;
        }
        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()
        {
            Log = Logger.CreatePublisher(GetType(), MessageClass.Framework);
            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
            m_publicationThread = new Thread(PublishFrames);
            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 = Common.TimerScheduler.CreateTimer(5000);
            m_monitorTimer.AutoReset = true;
            m_monitorTimer.Elapsed += MonitorUnpublishedSamples;
        }
Пример #8
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="DataSubscriber"/> 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 override void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        DataLossInterval = 0.0D;
                        CommandChannel = null;
                        DataChannel = null;
                        DisposeLocalConcentrator();

                        if ((object)m_dataGapRecoverer != null)
                        {
                            m_dataGapRecoverer.RecoveredMeasurements -= m_dataGapRecoverer_RecoveredMeasurements;
                            m_dataGapRecoverer.StatusMessage -= m_dataGapRecoverer_StatusMessage;
                            m_dataGapRecoverer.ProcessException -= m_dataGapRecoverer_ProcessException;
                            m_dataGapRecoverer.Dispose();
                            m_dataGapRecoverer = null;
                        }

                        if ((object)m_runTimeLog != null)
                        {
                            m_runTimeLog.ProcessException -= m_runTimeLog_ProcessException;
                            m_runTimeLog.Dispose();
                            m_runTimeLog = null;
                        }

                        if ((object)m_subscribedDevicesTimer != null)
                        {
                            m_subscribedDevicesTimer.Elapsed -= SubscribedDevicesTimer_Elapsed;
                            m_subscribedDevicesTimer.Dispose();
                            m_subscribedDevicesTimer = null;
                        }
                    }
                }
                finally
                {
                    m_disposed = true;          // Prevent duplicate dispose.
                    base.Dispose(disposing);    // Call base class Dispose().
                }
            }
        }
        /// <summary>
        /// Creates a new <see cref="ClientConnection"/> instance.
        /// </summary>
        /// <param name="parent">Parent data publisher.</param>
        /// <param name="clientID">Client ID of associated connection.</param>
        /// <param name="commandChannel"><see cref="TcpServer"/> command channel used to lookup connection information.</param>
        public ClientConnection(DataPublisher parent, Guid clientID, IServer commandChannel)
        {
            m_parent = parent;
            m_clientID = clientID;
            m_commandChannel = commandChannel;
            m_subscriberID = clientID;
            m_keyIVs = null;
            m_cipherIndex = 0;

            // Setup ping timer
            m_pingTimer = Common.TimerScheduler.CreateTimer(5000);
            m_pingTimer.AutoReset = true;
            m_pingTimer.Elapsed += m_pingTimer_Elapsed;
            m_pingTimer.Start();

            // Setup reconnect timer
            m_reconnectTimer = Common.TimerScheduler.CreateTimer(1000);
            m_reconnectTimer.AutoReset = false;
            m_reconnectTimer.Elapsed += m_reconnectTimer_Elapsed;

            // Attempt to lookup remote connection identification for logging purposes
            try
            {
                Socket commandChannelSocket = GetCommandChannelSocket();
                IPEndPoint remoteEndPoint = null;

                if ((object)commandChannel != null)
                    remoteEndPoint = commandChannelSocket.RemoteEndPoint as IPEndPoint;

                if ((object)remoteEndPoint != null)
                {
                    m_ipAddress = remoteEndPoint.Address;

                    if (remoteEndPoint.AddressFamily == AddressFamily.InterNetworkV6)
                        m_connectionID = "[" + m_ipAddress + "]:" + remoteEndPoint.Port;
                    else
                        m_connectionID = m_ipAddress + ":" + remoteEndPoint.Port;

                    try
                    {
                        IPHostEntry ipHost = Dns.GetHostEntry(remoteEndPoint.Address);

                        if (!string.IsNullOrWhiteSpace(ipHost.HostName))
                        {
                            m_hostName = ipHost.HostName;
                            m_connectionID = m_hostName + " (" + m_connectionID + ")";
                        }
                    }

                    // Just ignoring possible DNS lookup failures...
                    catch (ArgumentNullException)
                    {
                        // The hostNameOrAddress parameter is null. 
                    }
                    catch (ArgumentOutOfRangeException)
                    {
                        // The length of hostNameOrAddress parameter is greater than 255 characters. 
                    }
                    catch (ArgumentException)
                    {
                        // The hostNameOrAddress parameter is an invalid IP address. 
                    }
                    catch (SocketException)
                    {
                        // An error was encountered when resolving the hostNameOrAddress parameter.    
                    }
                }
            }
            catch
            {
                // At worst we'll just use the client GUID for identification
                m_connectionID = m_subscriberID == Guid.Empty ? clientID.ToString() : m_subscriberID.ToString();
            }

            if (string.IsNullOrWhiteSpace(m_connectionID))
                m_connectionID = "unavailable";

            if (string.IsNullOrWhiteSpace(m_hostName))
            {
                if ((object)m_ipAddress != null)
                    m_hostName = m_ipAddress.ToString();
                else
                    m_hostName = m_connectionID;
            }

            if ((object)m_ipAddress == null)
                m_ipAddress = IPAddress.None;
        }
Пример #10
0
        /// <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 ((object)m_publicationWaitHandle != null)
                        {
                            AutoResetEvent publicationWaitHandle = m_publicationWaitHandle;
                            m_publicationWaitHandle = null;
                            publicationWaitHandle.Set();
                            publicationWaitHandle.Dispose();
                        }

                        if ((object)m_frameQueue != null)
                        {
                            m_frameQueue.Dispose();
                            m_frameQueue = null;
                        }

                        if ((object)m_monitorTimer != null)
                        {
                            m_monitorTimer.Elapsed -= MonitorUnpublishedSamples;
                            m_monitorTimer.Dispose();
                            m_monitorTimer = null;
                        }

                        if ((object)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 ((object)Disposed != null)
                        Disposed(this, EventArgs.Empty);
                }
            }
        }
Пример #11
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="ClientConnection"/> 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)
                    {
                        if ((object)m_pingTimer != null)
                        {
                            m_pingTimer.Elapsed -= m_pingTimer_Elapsed;
                            m_pingTimer.Dispose();
                            m_pingTimer = null;
                        }

                        if ((object)m_reconnectTimer != null)
                        {
                            m_reconnectTimer.Elapsed -= m_reconnectTimer_Elapsed;
                            m_reconnectTimer.Dispose();
                            m_reconnectTimer = null;
                        }

                        DataChannel = null;
                        m_commandChannel = null;
                        m_ipAddress = null;
                        m_subscription = null;
                        m_parent = null;
                    }
                }
                finally
                {
                    m_disposed = true;  // Prevent duplicate dispose.
                }
            }
        }
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="MultiProtocolFrameParser"/> 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>
        private void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        Stop();

                        PrecisionInputTimer.Detach(ref m_inputTimer);

                        if ((object)m_rateCalcTimer != null)
                        {
                            m_rateCalcTimer.Elapsed -= m_rateCalcTimer_Elapsed;
                            m_rateCalcTimer.Dispose();
                        }
                        m_rateCalcTimer = null;

                        // Clear minimum timer resolution.
                        PrecisionTimer.ClearMinimumTimerResolution(1);
                    }
                }
                finally
                {
                    m_disposed = true;  // Prevent duplicate dispose.
                }
            }
        }
        /// <summary>
        /// Creates a new <see cref="MultiProtocolFrameParser"/> using the default settings.
        /// </summary>
        public MultiProtocolFrameParser()
        {
            m_connectionString = "server=127.0.0.1:4712";
            m_deviceID = 1;
            m_bufferSize = DefaultBufferSize;
            m_maximumConnectionAttempts = DefaultMaximumConnectionAttempts;
            m_autoStartDataParsingSequence = DefaultAutoStartDataParsingSequence;
            m_allowedParsingExceptions = DefaultAllowedParsingExceptions;
            m_parsingExceptionWindow = DefaultParsingExceptionWindow;
            m_checkSumValidationFrameTypes = CheckSumValidationFrameTypes.AllFrames;
            m_trustHeaderLength = true;
            m_keepCommandChannelOpen = true;
            m_rateCalcTimer = TimerScheduler.CreateTimer();

            m_phasorProtocol = PhasorProtocol.IEEEC37_118V1;
            m_transportProtocol = TransportProtocol.Tcp;

            // Set default frame rate, this calculates milliseconds for each frame
            DefinedFrameRate = DefaultDefinedFrameRate;

            m_rateCalcTimer.Elapsed += m_rateCalcTimer_Elapsed;
            m_rateCalcTimer.Interval = 5000;
            m_rateCalcTimer.AutoReset = true;
            m_rateCalcTimer.Enabled = false;

            // Set minimum timer resolution to one millisecond to improve timer accuracy
            PrecisionTimer.SetMinimumTimerResolution(1);
        }
        /// <summary>
        /// Creates a new <see cref="PhasorMeasurementMapper"/>.
        /// </summary>
        public PhasorMeasurementMapper()
        {
            // Create a cached signal reference dictionary for generated signal references
            m_generatedSignalReferenceCache = new ConcurrentDictionary<SignalKind, string[]>();

            // Create data stream monitoring timer
            m_dataStreamMonitor = CommonPhasorServices.TimerScheduler.CreateTimer();
            m_dataStreamMonitor.Elapsed += m_dataStreamMonitor_Elapsed;
            m_dataStreamMonitor.AutoReset = true;
            m_dataStreamMonitor.Enabled = false;

            m_undefinedDevices = new ConcurrentDictionary<string, long>();
            m_configurationOperationLock = new object();
        }
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="UnsynchronizedClientSubscription"/> 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 override void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        m_parent = null;

                        // Dispose base time rotation timer
                        if ((object)m_baseTimeRotationTimer != null)
                        {
                            m_baseTimeRotationTimer.Dispose();
                            m_baseTimeRotationTimer = null;
                        }

                        // Dispose Iaon session
                        this.DisposeTemporalSession(ref m_iaonSession);
                    }
                }
                finally
                {
                    m_disposed = true;          // Prevent duplicate dispose.
                    base.Dispose(disposing);    // Call base class Dispose().
                }
            }
        }
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="PhasorMeasurementMapper"/> 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 override void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        // Detach from frame parser events and set reference to null
                        FrameParser = null;

                        if ((object)m_dataStreamMonitor != null)
                        {
                            m_dataStreamMonitor.Elapsed -= m_dataStreamMonitor_Elapsed;
                            m_dataStreamMonitor.Dispose();
                            m_dataStreamMonitor = null;
                        }

                        if ((object)m_measurementCounter != null)
                        {
                            m_measurementCounter.Elapsed -= m_measurementCounter_Elapsed;
                            m_measurementCounter.Dispose();
                            m_measurementCounter = null;
                        }

                        if ((object)m_definedDevices != null)
                        {
                            // Unregister each existing device from the statistics engine
                            foreach (ConfigurationCell device in DefinedDevices)
                            {
                                StatisticsEngine.Unregister(device);
                            }
                        }
                    }
                }
                finally
                {
                    m_disposed = true;          // Prevent duplicate dispose.
                    base.Dispose(disposing);    // Call base class Dispose().
                }
            }
        }
        /// <summary>
        /// Initializes <see cref="UnsynchronizedClientSubscription"/>.
        /// </summary>
        public override void Initialize()
        {
            MeasurementKey[] inputMeasurementKeys;
            string setting;

            if (Settings.TryGetValue("inputMeasurementKeys", out setting))
            {
                // IMPORTANT: The allowSelect argument of ParseInputMeasurementKeys must be null
                //            in order to prevent SQL injection via the subscription filter expression
                inputMeasurementKeys = ParseInputMeasurementKeys(DataSource, false, setting);
                m_requestedInputFilter = setting;

                // IMPORTANT: We need to remove the setting before calling base.Initialize()
                //            or else we will still be subject to SQL injection
                Settings.Remove("inputMeasurementKeys");
            }
            else
            {
                inputMeasurementKeys = new MeasurementKey[0];
                m_requestedInputFilter = null;
            }

            base.Initialize();

            // Set the InputMeasurementKeys property after calling base.Initialize()
            // so that the base class does not overwrite our setting
            InputMeasurementKeys = inputMeasurementKeys;

            if (Settings.TryGetValue("publishInterval", out setting))
                m_publishInterval = int.Parse(setting);
            else
                m_publishInterval = -1;

            if (Settings.TryGetValue("includeTime", out setting))
                m_includeTime = setting.ParseBoolean();
            else
                m_includeTime = true;

            if (Settings.TryGetValue("useMillisecondResolution", out setting))
                m_useMillisecondResolution = setting.ParseBoolean();
            else
                m_useMillisecondResolution = false;

            if (Settings.TryGetValue("requestNaNValueFilter", out setting))
                m_isNaNFiltered = m_parent.AllowNaNValueFilter && setting.ParseBoolean();
            else
                m_isNaNFiltered = false;

            if (Settings.TryGetValue("bufferBlockRetransmissionTimeout", out setting))
                m_bufferBlockRetransmissionTimeout = double.Parse(setting);
            else
                m_bufferBlockRetransmissionTimeout = 5.0D;

            if (m_parent.UseBaseTimeOffsets && m_includeTime)
            {
                m_baseTimeRotationTimer = Common.TimerScheduler.CreateTimer(m_useMillisecondResolution ? 60000 : 420000);
                m_baseTimeRotationTimer.AutoReset = true;
                m_baseTimeRotationTimer.Elapsed += BaseTimeRotationTimer_Elapsed;
            }

            m_bufferBlockRetransmissionTimer = Common.TimerScheduler.CreateTimer((int)(m_bufferBlockRetransmissionTimeout * 1000.0D));
            m_bufferBlockRetransmissionTimer.AutoReset = false;
            m_bufferBlockRetransmissionTimer.Elapsed += BufferBlockRetransmissionTimer_Elapsed;

            // Handle temporal session initialization
            if (this.TemporalConstraintIsDefined())
                m_iaonSession = this.CreateTemporalSession();
        }
Пример #18
0
        /// <summary>
        /// Attempts to connect to this <see cref="DataSubscriber"/>.
        /// </summary>
        protected override void AttemptConnection()
        {
            long now = m_useLocalClockAsRealTime ? DateTime.UtcNow.Ticks : 0L;
            List<DeviceStatisticsHelper<SubscribedDevice>> statisticsHelpers = m_statisticsHelpers;

            m_registerStatisticsOperation.RunOnceAsync();
            m_expectedBufferBlockSequenceNumber = 0u;
            m_commandChannelConnectionAttempts = 0;
            m_dataChannelConnectionAttempts = 0;

            m_authenticated = m_securityMode == SecurityMode.TLS;
            m_subscribed = false;
            m_keyIVs = null;
            m_totalBytesReceived = 0L;
            m_monitoredBytesReceived = 0L;
            m_lastBytesReceived = 0;

            m_commandChannel.ConnectAsync();

            if (m_useLocalClockAsRealTime && (object)m_subscribedDevicesTimer == null)
            {
                m_subscribedDevicesTimer = Common.TimerScheduler.CreateTimer(1000);
                m_subscribedDevicesTimer.Elapsed += SubscribedDevicesTimer_Elapsed;
            }

            if ((object)statisticsHelpers != null)
            {
                m_realTime = 0L;
                m_lastStatisticsHelperUpdate = 0L;

                foreach (DeviceStatisticsHelper<SubscribedDevice> statisticsHelper in statisticsHelpers)
                    statisticsHelper.Reset(now);
            }

            if (m_useLocalClockAsRealTime)
                m_subscribedDevicesTimer.Start();
        }
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="OutputAdapterBase"/> 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 override void Dispose(bool disposing)
        {
            if (!m_disposed)
            {
                try
                {
                    if (disposing)
                    {
                        if (m_connectionTimer != null)
                        {
                            m_connectionTimer.Elapsed -= m_connectionTimer_Elapsed;
                            m_connectionTimer.Dispose();
                        }
                        m_connectionTimer = null;

                        if (m_monitorTimer != null)
                        {
                            m_monitorTimer.Elapsed -= m_monitorTimer_Elapsed;
                            m_monitorTimer.Dispose();
                        }
                        m_monitorTimer = null;

                        if (m_measurementQueue != null)
                        {
                            m_measurementQueue.ProcessException -= m_measurementQueue_ProcessException;
                            m_measurementQueue.Dispose();
                        }
                        m_measurementQueue = null;
                    }
                }
                finally
                {
                    m_disposed = true;          // Prevent duplicate dispose.
                    base.Dispose(disposing);    // Call base class Dispose().
                }
            }
        }