Opc.Ua.Com.Server.ComDaGroup.OnUpdate C# (CSharp) Method

OnUpdate() private method

Called when it is time to send an update.
private OnUpdate ( object state ) : void
state object The state.
return void
        private void OnUpdate(object state)
        {
            try
            {
                IComDaGroupCallback callback = null;
                List<int> clientHandles = null;
                List<DaValue> values = null;
                long now = HiResClock.UtcNow.Ticks;

                lock (m_lock)
                {
                    // check if updates are required.
                    if (!AreUpdatesRequired || m_updateInProgress)
                    {
                        TraceState("OnUpdate Skipped");
                        return;
                    }

                    // check if enough time has elapsed.
                    if (m_nextUpdateTime == -1 || m_nextUpdateTime > (now + 50*TimeSpan.TicksPerMillisecond))
                    {             
                        return;
                    }

                    // Utils.Trace("NextUpdateTime={0:mm:ss.fff}, CurrentTime={1:mm:ss.fff}", new DateTime(m_nextUpdateTime), new DateTime(now));

                    // collect values to report.
                    for (int ii = 0; ii < m_items.Count; ii++)
                    {
                        ComDaGroupItem item = m_items[ii];

                        if (!item.Active)
                        {
                            continue;
                        }

                        if (item.CacheEntry == null || !item.CacheEntry.Changed)
                        {
                            continue;
                        }

                        // write buffered values first.
                        DaValue value = null;

                        if (item.CacheEntry.NextEntry != null)
                        {
                            Stack<DaCacheValue> stack = new Stack<DaCacheValue>();

                            for (DaCacheValue entry = item.CacheEntry; entry != null; entry = entry.NextEntry)
                            {
                                stack.Push(entry);
                            }

                            while (stack.Count > 1)
                            {
                                DaCacheValue entry = stack.Pop();

                                value = new DaValue();
                                entry.GetLatest(value);
                                UpdateReadResult(item, value);

                                if (item.LastSentValue != null)
                                {
                                    if (value.Quality == item.LastSentValue.Quality)
                                    {
                                        if (Utils.IsEqual(item.LastSentValue.Value, value.Value))
                                        {
                                            continue;
                                        }
                                    }
                                }

                                if (clientHandles == null)
                                {
                                    clientHandles = new List<int>();
                                    values = new List<DaValue>();
                                }

                                clientHandles.Add(item.ClientHandle);
                                values.Add(value);
                                item.LastSentValue = value;

                                /*
                                TraceState(
                                    "OnUpdate BUFFERED VALUE",
                                    this.m_serverHandle,
                                    item.ServerHandle,
                                    item.ClientHandle,
                                    new Variant(value.Value),
                                    value.Timestamp.ToString("HH:mm:ss.fff"),
                                    item.CacheEntry.Changed);
                                */
                            }

                            // clear cache.
                            item.CacheEntry.NextEntry = null;
                        }

                        // check if enough time has elapsed for this item (used if the sampling rate > update rate).
                        if (item.NextUpdateTime != -1 && item.NextUpdateTime > now)
                        {
                            continue;
                        }

                        // add latest values.
                        value = new DaValue();
                        item.CacheEntry.GetLatest(value);
                        UpdateReadResult(item, value);

                        if (item.LastSentValue != null)
                        {
                            if (value.Quality == item.LastSentValue.Quality)
                            {
                                if (Utils.IsEqual(item.LastSentValue.Value, value.Value))
                                {
                                    item.CacheEntry.Changed = false;
                                    continue;
                                }
                            }
                        }

                        if (clientHandles == null)
                        {
                            clientHandles = new List<int>();
                            values = new List<DaValue>();
                        }

                        clientHandles.Add(item.ClientHandle);
                        values.Add(value);
                        item.LastSentValue = value;

                        /*
                        TraceState(
                            "OnUpdate LATEST VALUE",
                            this.m_serverHandle,
                            item.ServerHandle,
                            item.ClientHandle,
                            new Variant(value.Value),
                            value.Timestamp.ToString("HH:mm:ss.fff"),
                            item.CacheEntry.Changed);
                        */

                        // clear change flag.
                        item.CacheEntry.Changed = false;
                    }

                    // nothing to report unless the keep alive expired.
                    if (clientHandles == null || clientHandles.Count == 0)
                    {
                        if (m_keepAliveTime == 0 || m_lastUpdateTime + m_keepAliveTime*TimeSpan.TicksPerMillisecond > now)
                        {
                            ScheduleNextUpdate();
                            return;
                        }
                    }

                    callback = m_callback;
                    m_updateInProgress = true;
                    m_lastUpdateTime = now;

                    // schedule next update.
                    ScheduleNextUpdate();
                }

                // send callback.
                try
                {
                    callback.ReadCompleted(
                        this.m_clientHandle,
                        false,
                        0,
                        0,
                        (clientHandles != null) ? clientHandles.ToArray() : new int[0],
                        (values != null) ? values.ToArray() : new DaValue[0]);

                    if (clientHandles.Count > 0)
                    {
                        m_manager.SetLastUpdateTime();
                    }
                    
                    /*
                    TraceState(
                        "OnUpdate Completed", 
                        this.m_serverHandle,
                        (values != null && values.Count > 0)?values[0].Value:"null", 
                        (m_nextUpdateTime-now)/TimeSpan.TicksPerMillisecond);
                    */
                }
                finally
                {
                    lock (m_lock)
                    {
                        m_updateInProgress = false;
                    }
                }
            }
            catch (Exception e)
            {
                Utils.Trace("Unexpected error during GroupUpdate. {0}", e.Message);
            }
        }