private void                                        MC_IMDB_WriteRead()
        {
            int lCount = mItemRWList.Count;

            for (int i = 0; i < lCount; i++)
            {
                mCurrentItem = mItemRWList[i];

                if (mDisconnect)
                {
                    break;
                }

                if (mCurrentItem.mMemoryType != EPLCMemoryType.Q)
                {
                    try
                    {
                        #region Write

                        if (mCurrentItem.mNeedWrite)
                        {
                            mWriteRequests = mWriteRequests + 1;
                            mCurrentItem.write(mS7ProSim);
                        }

                        #endregion

                        if (mDisconnect)
                        {
                            break;
                        }

                        #region Read

                        if (mCurrentItem.mNeedWrite != true)
                        {
                            mCurrentItem.read(mS7ProSim);
                        }

                        #endregion

                        if (mDisconnect)
                        {
                            break;
                        }

                        mSlowCounter = mSlowCounter + mDeltaSlow;
                        if (mSlowCounter >= 1.0D)
                        {
                            mSlowCounter = mSlowCounter - 1.0D;

                            Thread.Sleep(MiscUtils.TimeSlice);
                        }
                    }
                    catch (Exception lExc)
                    {
                        mDisconnect = true;
                        raiseConnectionError(lExc.Message);
                    }
                }

                mCurrentItem = null;
            }
        }
        private void MC_IMDB_WriteRead()
        {
            int lCount = mItemRWList.Count;

            for (int i = 0; i < lCount; i++)
            {
                mCurrentItem = mItemRWList[i];

                if (mDisconnect) { break; }

                if (mCurrentItem.mMemoryType != EPLCMemoryType.Q)
                {
                    try
                    {
                        #region Write

                            if (mCurrentItem.mNeedWrite)
                            {
                                mWriteRequests = mWriteRequests + 1;
                                mCurrentItem.write(mS7ProSim);
                            }

                        #endregion

                        if (mDisconnect) { break; }

                        #region Read

                            if (mCurrentItem.mNeedWrite != true)
                            {
                                mCurrentItem.read(mS7ProSim);
                            }

                        #endregion

                        if (mDisconnect) { break; }

                        mSlowCounter = mSlowCounter + mDeltaSlow;
                        if (mSlowCounter >= 1.0D)
                        {
                            mSlowCounter = mSlowCounter - 1.0D;

                            Thread.Sleep(MiscUtils.TimeSlice);
                        }
                    }
                    catch (Exception lExc)
                    {
                        mDisconnect = true;
                        raiseConnectionError(lExc.Message);
                    }
                }

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

            if (mDisconnect == false)
            {
                try
                {
                    mS7ProSim.GetState();

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

                        if (mItemListChanged)
                        {
                            mItemRWList.Clear();
                            mItemListLock.EnterReadLock();
                            //========================================
                            try
                            {
                                mItemRWList.AddRange(mItemList);
                                mItemListChanged = false;
                            }
                            finally
                            {
                                //========================================
                                mItemListLock.ExitReadLock();
                            }

                            mQLength   = 0;
                            mQOptimise = true;
                        }
                        else if (mQOptimise)
                        {
                            mQOptimise = false;
                            optimise();
                        }

                        #endregion

                        if (mQLength > 0)
                        {
                            Task lQ = new Task(MC_Q_Read);
                            lQ.Start();

                            Task lIMDB = new Task(MC_IMDB_WriteRead);
                            lIMDB.Start();

                            Task.WaitAll(lQ, lIMDB);
                        }
                        else
                        {
                            int lCount = mItemRWList.Count;

                            for (int i = 0; i < lCount; i++)
                            {
                                mCurrentItem = mItemRWList[i];

                                if (mDisconnect)
                                {
                                    break;
                                }

                                #region Write

                                if (mCurrentItem.mNeedWrite)
                                {
                                    mWriteRequests = mWriteRequests + 1;
                                    mCurrentItem.write(mS7ProSim);
                                }

                                #endregion

                                if (mDisconnect)
                                {
                                    break;
                                }

                                #region Read

                                if (mCurrentItem.mNeedWrite != true)
                                {
                                    mCurrentItem.read(mS7ProSim);
                                }

                                #endregion

                                if (mDisconnect)
                                {
                                    break;
                                }

                                mSlowCounter = mSlowCounter + mDeltaSlow;
                                if (mSlowCounter >= 1.0D)
                                {
                                    mSlowCounter = mSlowCounter - 1.0D;
                                    Thread.Sleep(MiscUtils.TimeSlice);
                                }
                            }

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

            mMainCycleTimeMS = MiscUtils.TimerMS - lStartMS;

            if (mDisconnect)
            {
                mS7ProSim.EndScanNotify();
                mS7ProSim.Disconnect();

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

            if (mDisconnect == false)
            {
                try
                {
                    mS7ProSim.GetState();

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

                            if (mItemListChanged)
                            {
                                mItemRWList.Clear();
                                mItemListLock.EnterReadLock();
                                //========================================
                                try
                                {
                                    mItemRWList.AddRange(mItemList);
                                    mItemListChanged = false;
                                }
                                finally
                                {
                                    //========================================
                                    mItemListLock.ExitReadLock();
                                }

                                mQLength    = 0;
                                mQOptimise  = true;
                            }
                            else if (mQOptimise)
                            {
                                mQOptimise = false;
                                optimise();
                            }

                        #endregion

                        if (mQLength > 0)
                        {
                            Task lQ = new Task(MC_Q_Read);
                            lQ.Start();

                            Task lIMDB = new Task(MC_IMDB_WriteRead);
                            lIMDB.Start();

                            Task.WaitAll(lQ, lIMDB);
                        }
                        else
                        {
                            int lCount = mItemRWList.Count;

                            for (int i = 0; i < lCount; i++)
                            {
                                mCurrentItem = mItemRWList[i];

                                if (mDisconnect) { break; }

                                #region Write

                                    if (mCurrentItem.mNeedWrite)
                                    {
                                        mWriteRequests = mWriteRequests + 1;
                                        mCurrentItem.write(mS7ProSim);
                                    }

                                #endregion

                                if (mDisconnect) { break; }

                                #region Read

                                    if (mCurrentItem.mNeedWrite != true)
                                    {
                                        mCurrentItem.read(mS7ProSim);
                                    }

                                #endregion

                                if (mDisconnect) { break; }

                                mSlowCounter = mSlowCounter + mDeltaSlow;
                                if (mSlowCounter >= 1.0D)
                                {
                                    mSlowCounter = mSlowCounter - 1.0D;
                                    Thread.Sleep(MiscUtils.TimeSlice);
                                }
                            }

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

            mMainCycleTimeMS = MiscUtils.TimerMS - lStartMS;

            if (mDisconnect)
            {
                mS7ProSim.EndScanNotify();
                mS7ProSim.Disconnect();

                mConnected = false;
                raiseConnectionState();
                mCycleEndEvent.Set();
                mDisconnectEvent.Set();
            }
            else
            {
                mMainCycleTimer.Start();
                mCycleEndEvent.Set();
            }
        }