private void                                        MainCycle(object aSender, ElapsedEventArgs aEventArgs)
        {
            long lStartMS = MiscUtils.TimerMS;

            if (mDisconnect)
            {
                goto End;
            }

            if (mItemList.Count != 0)
            {
                try
                {
                    #region Item List Changed

                    if (mItemListChanged)
                    {
                        mItemRWList.Clear();
                        mItemListLock.EnterReadLock();
                        //========================================
                        try
                        {
                            mItemRWList.AddRange(mItemList);
                            var lCount = mItemList.Count;
                            mSDataValue = new SDataValueByNameWithCheck[lCount];
                            for (int i = 0; i < lCount; i++)
                            {
                                var lDataValue = new SDataValueByNameWithCheck();
                                lDataValue.Name = mItemList[i].mTagName;

                                mSDataValue[i] = lDataValue;
                            }

                            mItemListChanged = false;
                        }
                        finally
                        {
                            //========================================
                            mItemListLock.ExitReadLock();
                        }
                    }

                    #endregion

                    if (mDisconnect)
                    {
                        goto End;
                    }

                    bool lNewValues;
                    try
                    {
                        mPLC.ReadSignals(ref mSDataValue, out lNewValues);
                    }
                    catch (SimulationRuntimeException lExc)
                    {
                        if (lExc.RuntimeErrorCode != ERuntimeErrorCode.SignalConfigurationError)
                        {
                            throw new InvalidOperationException(ErrorCodeMessage(lExc.RuntimeErrorCode), lExc);
                        }
                    }

                    if (mDisconnect)
                    {
                        goto End;
                    }

                    for (int i = 0; i < mSDataValue.Length; i++)
                    {
                        if (mItemRWList[i].mNeedWrite)
                        {
                            mItemRWList[i].mNeedWrite = false;
                            mWriteRequests            = mWriteRequests + 1;

                            mPLC.Write(mItemRWList[i].mTagName, mItemRWList[i].getValue());
                        }
                        else
                        {
                            if (mSDataValue[i].ErrorCode == ERuntimeErrorCode.OK)
                            {
                                mItemRWList[i].Access = EAccess.READ_WRITE;
                            }
                            else
                            {
                                mItemRWList[i].Access = EAccess.NO_ACCESS;
                            }

                            if (mSDataValue[i].ValueHasChanged)
                            {
                                mItemRWList[i].setValue(mSDataValue[i].DataValue);
                            }
                        }
                        if (mDisconnect)
                        {
                            goto End;
                        }
                    }

                    pause();
                }
                catch (Exception lExc)
                {
                    mDisconnect = true;
                    raiseConnectionError(lExc.Message);
                }
            }

            mMainCycleTimeMS = MiscUtils.TimerMS - lStartMS;

End:
            if (mDisconnect)
            {
                mConnected = false;
                raiseConnectionState();
                mDisconnectEvent.Set();
            }
            else
            {
                mMainCycleTimer.Start();
            }
        }
        private void                                        MainCycle(object aSender, ElapsedEventArgs aEventArgs)
        {
            long lStartMS = MiscUtils.TimerMS;

            if (mDisconnect)
            {
                goto End;
            }

            if (mItemList.Count != 0)
            {
                try
                {
                    #region Item List Changed

                    if (mItemListChanged)
                    {
                        mItemRWList.Clear();
                        mItemListLock.EnterReadLock();
                        //========================================
                        try
                        {
                            mItemRWList.AddRange(mItemList);
                            var lCount = mItemList.Count;
                            mSDataValue = new SDataValueByNameWithCheck[lCount];
                            for (int i = 0; i < lCount; i++)
                            {
                                var lDataValue = new SDataValueByNameWithCheck();
                                lDataValue.Name = mItemList[i].mTagName;

                                mSDataValue[i] = lDataValue;
                            }

                            mItemListChanged = false;
                        }
                        finally
                        {
                            //========================================
                            mItemListLock.ExitReadLock();
                        }
                    }

                    #endregion

                    if (mDisconnect)
                    {
                        goto End;
                    }

                    bool lNewValues;

                    if (mTagUpdateNeeded)
                    {
                        try
                        {
                            mPLC.UpdateTagList();
                        }
                        catch (SimulationRuntimeException lExc)
                        {
                            throw new InvalidOperationException(ErrorCodeMessage(lExc.RuntimeErrorCode), lExc);
                        }

                        try
                        {
                            mPLC.ReadSignals(ref mSDataValue, out lNewValues);
                            mTagUpdateNeeded = false;
                        }
                        catch (SimulationRuntimeException lExc)
                        {
                            if (lExc.RuntimeErrorCode != ERuntimeErrorCode.SignalConfigurationError &&
                                lExc.RuntimeErrorCode != ERuntimeErrorCode.NotUpToDate)
                            {
                                throw new InvalidOperationException(ErrorCodeMessage(lExc.RuntimeErrorCode), lExc);
                            }

                            if (lExc.RuntimeErrorCode != ERuntimeErrorCode.NotUpToDate)
                            {
                                mTagUpdateNeeded = false;
                            }
                        }

                        if (mTagUpdateNeeded == false)
                        {
                            Log.Info("PLC '" + mPLCName + "'. The stored tag list update completed. ");

                            foreach (var lItem in mItemRWList)
                            {
                                lItem.mUnlockWrite = true;
                            }

                            for (int i = 0; i < mSDataValue.Length; i++)
                            {
                                if (mDisconnect)
                                {
                                    goto End;
                                }

                                if (mItemRWList[i].mNeedWrite == false)
                                {
                                    if (mSDataValue[i].ErrorCode == ERuntimeErrorCode.OK)
                                    {
                                        mItemRWList[i].Access = EAccess.READ_WRITE;
                                    }
                                    else
                                    {
                                        mItemRWList[i].Access = EAccess.NO_ACCESS;
                                    }

                                    if (mSDataValue[i].ValueHasChanged)
                                    {
                                        mItemRWList[i].setValue(mSDataValue[i].DataValue);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        try
                        {
                            mPLC.ReadSignals(ref mSDataValue, out lNewValues);
                        }
                        catch (SimulationRuntimeException lExc)
                        {
                            if (lExc.RuntimeErrorCode == ERuntimeErrorCode.NotUpToDate)
                            {
                                mTagUpdateNeeded = true;
                                Log.Info("PLC '" + mPLCName + "'. The stored tag list must be updated. ");
                            }
                            else if (lExc.RuntimeErrorCode != ERuntimeErrorCode.SignalConfigurationError)
                            {
                                throw new InvalidOperationException(ErrorCodeMessage(lExc.RuntimeErrorCode), lExc);
                            }
                        }

                        if (mDisconnect)
                        {
                            goto End;
                        }

                        handleValues();
                    }

                    pause();
                }
                catch (Exception lExc)
                {
                    mDisconnect = true;
                    raiseConnectionError(lExc.Message);
                }
            }

            mMainCycleTimeMS = MiscUtils.TimerMS - lStartMS;

End:
            if (mDisconnect)
            {
                mConnected = false;
                raiseConnectionState();
                mDisconnectEvent.Set();
            }
            else
            {
                if (mTagUpdateNeeded)
                {
                    mMainCycleTimer.Interval = 5000;
                }
                else
                {
                    mMainCycleTimer.Interval = MiscUtils.TimeSlice;
                }

                mMainCycleTimer.Start();
            }
        }