예제 #1
0
        public void RemoveWriteRequest(TNDWriteRequest theRequest)
        {
//            lock (masterListLock)
            using (TimedLock.Lock(masterListLock))
            {
                mWriteRequests_all.Remove(theRequest);

                if (theRequest.Active)
                {
                    mTagListDirty = true;
                }
            }
        }
예제 #2
0
        public void RemoveReadRequest(TNDReadRequest theRequest)
        {
//            lock (masterListLock) // updating the tagList requires interating through the master requests list...we can't change the list during iteration...consider a separate masterListLock to minized lock area (e.g. not the entire "updateTagList & read" process
            using (TimedLock.Lock(masterListLock))
            {
                mReadRequests_all.Remove(theRequest);

                if (theRequest.Active)
                {
                    mTagListDirty = true;
                }
            }
        }
예제 #3
0
        public static TimedLock Lock(object o, TimeSpan timeout)
        {
            TimedLock tl = new TimedLock(o);

            if (!Monitor.TryEnter(o, timeout))
            {
#if DEBUG
                System.GC.SuppressFinalize(tl.leakDetector);
#endif
                throw new LockTimeoutException();
            }

            return(tl);
        }
예제 #4
0
        public OperationForm GetNewWaitingForm()
        {
            OperationForm aForm = null;

            using (TimedLock.Lock(mNewFormsThatNeedButtonListeners)) // LOCKING FOR THREAD SAFETY
            {
                if (mNewFormsThatNeedButtonListeners.Count > 0)
                {
                    aForm = mNewFormsThatNeedButtonListeners[0];
                    mNewFormsThatNeedButtonListeners.RemoveAt(0);
                }

                if (mNewFormsThatNeedButtonListeners.Count == 0)
                {
                    mNewFormWaiting = false;
                }
            }
            return(aForm);
        }
예제 #5
0
        public void AddWriteRequest(TNDWriteRequest theRequest)
        {
            if (!Connected)
            {
                Connected = true;
            }

            //            lock (masterListLock)
            using (TimedLock.Lock(masterListLock))
            {
                if (mWriteRequests_all.Contains(theRequest))
                {
                    throw new ArgumentException("How did we get here?");
                }
                mWriteRequests_all.Add(theRequest);

                if (theRequest.Active)
                {
                    mTagListDirty = true;
                }
            }
        }
예제 #6
0
        public void AddReadRequest(TNDReadRequest theRequest)
        {
            if (!Connected)
            {
                Connected = true;
            }

//            lock (masterListLock) // updating the tagList requires interating through the master requests list...we can't change the list during iteration...consider a separate masterListLock to minized lock area (e.g. not the entire "updateTagList & read" process
            using (TimedLock.Lock(masterListLock))
            {
                if (mReadRequests_all.Contains(theRequest))
                {
                    throw new ArgumentException("How did we get here?");
                }
                mReadRequests_all.Add(theRequest);
                mReadRequests_all.Sort(ReadRequestSorter.Singleton);

                if (theRequest.Active)
                {
                    mTagListDirty = true;
                }
            }
        }
예제 #7
0
        protected override void mPollTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs eventArgs)
        {
            mPollTimer.Enabled    = false;
            mTimeoutTimer.Enabled = true;

            mStarted = DateTime.Now;

            if (Project().FullyInitialized)
            {
                mTimeoutStateIndicator = "Starting Poll";
                try
                {
                    mTimeoutStateIndicator = "Entering lock";
                    //                lock (masterListLock)
                    using (TimedLock.Lock(masterListLock))
                    {
                        mTimeoutStateIndicator = "Checking if tag list dirty";
                        mGotLock = DateTime.Now;
                        mLockAttainment.NewPeriod(mStarted, mGotLock);

                        if (mTagListDirty)
                        {
                            // start with an empty tag list
                            mTimeoutStateIndicator = "Clearing tag list";
                            mReadRequestsInTagList.Clear();
                            int result = axTndNTag.ClearTagList();
                            if (result != ThinkAndDoSuccess)
                            {
                                mProject.Window().logMessage("ERROR: problem clearing tag list. code=" + result);
                                HandleLostConnection();
                                return;
                            }

                            // build list
                            mTimeoutStateIndicator = "starting tag list";
                            result = axTndNTag.StartTagList();
                            if (result != ThinkAndDoSuccess)
                            {
                                mProject.Window().logMessage("ERROR: problem initiating tag list. code=" + result);
                                HandleLostConnection();
                                return;
                            }

                            mTimeoutStateIndicator = "sorting read requests";
                            mReadRequests_all.Sort(ReadRequestSorter.Singleton);
                            mTimeoutStateIndicator = "building tag list";
                            TNDReadRequest lastReq = null;
                            foreach (TNDReadRequest req in mReadRequests_all)
                            {
                                if (req.Active)
                                {
                                    // only add unique ones to the taglist...the requests should be shorted by Type & Index
                                    if (lastReq == null || req.TNDDataTypeAsShort() != lastReq.TNDDataTypeAsShort() || req.TNDDataViewIndex != lastReq.TNDDataViewIndex)
                                    {
                                        result = axTndNTag.AddToTagList(req.TNDDataTypeAsShort(), req.TNDDataViewIndex, "");
                                        if (result != ThinkAndDoSuccess)
                                        {
                                            mProject.Window().logMessage("ERROR: adding to tag list. code=" + result + "  type=" + req.TNDDataTypeAsShort() + "  index=" + req.TNDDataViewIndex);
                                            HandleLostConnection();
                                            return;
                                        }
                                    }
                                    mReadRequestsInTagList.Add(req);
                                    lastReq = req;
                                }
                            }

                            mTimeoutStateIndicator = "ending tag list";
                            result = axTndNTag.EndTagList();
                            if (result != ThinkAndDoSuccess)
                            {
                                mProject.Window().logMessage("ERROR: problem closing tag list. code=" + result);
                                HandleLostConnection();
                                return;
                            }

                            mTagListDirty   = false;
                            mTagListUpdated = DateTime.Now;
                            mTagListUpdate.NewPeriod(mGotLock, mTagListUpdated);
                        }
                        mTimeoutStateIndicator = "exit lock";

                        if (mReadRequestsInTagList.Count > 0)
                        {
                            mTimeoutStateIndicator = "starting read";
                            mStartRead             = DateTime.Now;

                            int result = -99911999;
                            try
                            {
                                result = axTndNTag.Read();
                            }
                            catch (COMException comException)
                            {
                                mProject.Window().logMessage("ERROR: COM Exception during TND read attempt. code=" + comException.ErrorCode + "  msg=" + comException.Message);
                            }
                            catch (Exception exception)
                            {
                                mProject.Window().logMessage("ERROR: Exception during TND read attempt. msg=" + exception.Message);
                            }
                            mValuesRead = DateTime.Now;
                            mValuesRetrieval.NewPeriod(mStartRead, mValuesRead);

                            if (result == TNDLink.ThinkAndDoSuccess)
                            {
                                mTimeoutStateIndicator = "finished read successfully";
                                short          requestIndex = 0;
                                TNDReadRequest lastReq      = null;
                                object         valueFromTND = null;
                                foreach (TNDReadRequest req in mReadRequestsInTagList)
                                {
                                    mTimeoutStateIndicator = "processing value " + requestIndex + " of " + mReadRequestsInTagList.Count + ": " + req.TNDDataType + " " + req.TNDDataViewIndex;
                                    if (lastReq == null || req.TNDDataTypeAsShort() != lastReq.TNDDataTypeAsShort() || req.TNDDataViewIndex != lastReq.TNDDataViewIndex)
                                    {
                                        valueFromTND           = axTndNTag.GetValueAt(requestIndex);
                                        mTimeoutStateIndicator = "got value";
                                        if (valueFromTND == null)
                                        {
                                            Project().Window().logMessageWithFlush("ERROR: value from TND is null; index=" + requestIndex + "  taglist size=" + mReadRequestsInTagList.Count + "  unique requests=" + mReadRequests_all.Count + "  dirty=" + mTagListDirty);
                                        }
                                        requestIndex++;
                                    }
                                    if (valueFromTND != null)
                                    {
                                        mTimeoutStateIndicator = "going to handler";
                                        req.HandleValue(valueFromTND);
                                    }
                                    mTimeoutStateIndicator = "finished processing value " + requestIndex;
                                    lastReq = req;
                                }
                                mValuesHandled = DateTime.Now;
                                mValuesHandling.NewPeriod(mValuesRead, mValuesHandled);
                            }
                            else
                            {
                                mTimeoutStateIndicator = "finished read with ERRORS";
                                if (result != lastResult)
                                {
                                    mProject.Window().logMessage("ERROR: TND Read failed for '" + Name + "': " + TNDLink.GetTNDResultMessage(result));
                                }
                                HandleLostConnection();
                            }
                            lastResult = result;
                        }
                    } // end thread lock
                }
                catch (Exception e)
                {
                    mProject.Window().logMessage("ERROR: Exception in TND Reader " + Name + "; msg=" + e.Message + Environment.NewLine + e.StackTrace);
                }
            }

            if (Connected)
            {
                mTimeoutStateIndicator = "restarting poll timer";
                mPollTimer.Enabled     = true;
            }
            mTimeoutStateIndicator = "poll completed";
            mTimeoutTimer.Enabled  = false;
        }
예제 #8
0
        protected override void mPollTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs eventArgs)
        {
            mPollTimer.Enabled    = false;
            mTimeoutTimer.Enabled = true;

            mStarted = DateTime.Now;
            if (Project().FullyInitialized)
            {
                mNumberOfSums++;
                DateTime now = DateTime.Now;
                if (mNumberOfSums > 1) //ignore the first one (==1) since mLastPollTime won't be init'ed
                {
                    TimeSpan period     = now - mLastPollTime;
                    int      periodInMS = (int)period.TotalMilliseconds;
                    if (periodInMS < mMinPeriodBetweenPolls)
                    {
                        mMinPeriodBetweenPolls = periodInMS;
                    }
                    if (periodInMS > mMaxPeriodBetweenPolls)
                    {
                        mMaxPeriodBetweenPolls = periodInMS;
                    }
                    mSumPeriodBetweenPolls    += periodInMS;
                    mAveragePeriodBetweenPolls = (int)(mSumPeriodBetweenPolls / (mNumberOfSums - 1));
                }
                mLastPollTime = now;

                mTimeoutStateIndicator = "Starting Poll";

                try
                {
                    mTimeoutStateIndicator = "Entering lock";
                    //                lock (masterListLock)
                    using (TimedLock.Lock(masterListLock))
                    {
                        mTimeoutStateIndicator = "Checking if tag list dirty";
                        mGotLock = DateTime.Now;
                        mLockAttainment.NewPeriod(mStarted, mGotLock);

                        if (mTagListDirty)
                        {
                            //                        mProject.Window().logMessage(Name + " updating tag list " + mWriteRequestsInTagList.Count + " " + mWriteRequests_all.Count);
                            // start with an empty tag list
                            mTimeoutStateIndicator = "Clearing tag list";
                            mWriteRequestsInTagList.Clear();
                            int result = axTndNTag.ClearTagList();
                            if (result != ThinkAndDoSuccess)
                            {
                                mProject.Window().logMessage("ERROR: problem clearing tag list. code=" + result);
                                HandleLostConnection();
                                return;
                            }

                            // build list
                            mTimeoutStateIndicator = "starting tag list";
                            result = axTndNTag.StartTagList();
                            if (result != ThinkAndDoSuccess)
                            {
                                mProject.Window().logMessage("ERROR: problem initiating tag list. code=" + result);
                                HandleLostConnection();
                                return;
                            }

                            mTimeoutStateIndicator = "building tag list";
                            foreach (TNDWriteRequest req in mWriteRequests_all)
                            {
                                if (req.Active)
                                {
                                    result = axTndNTag.AddToTagList(req.TNDDataTypeAsShort(), req.TNDDataViewIndex, "");
                                    if (result != ThinkAndDoSuccess)
                                    {
                                        mProject.Window().logMessage("ERROR: adding to tag list. code=" + result + "  type=" + req.TNDDataTypeAsShort() + "  index=" + req.TNDDataViewIndex);
                                        HandleLostConnection();
                                        return;
                                    }
                                    mWriteRequestsInTagList.Add(req);
                                }
                            }

                            mTimeoutStateIndicator = "ending tag list";
                            result = axTndNTag.EndTagList();
                            if (result != ThinkAndDoSuccess)
                            {
                                mProject.Window().logMessage("ERROR: problem closing tag list. code=" + result);
                                HandleLostConnection();
                                return;
                            }

                            mTagListDirty   = false;
                            mTagListUpdated = DateTime.Now;
                            mTagListUpdate.NewPeriod(mGotLock, mTagListUpdated);
                            //                        mProject.Window().logMessage(Name + " tag list update complete " + mWriteRequestsInTagList.Count + " " + mWriteRequests_all.Count);
                        }
                        mTimeoutStateIndicator = "exit lock";
                    } // end thread lock

                    if (mWriteRequestsInTagList.Count > 0)
                    {
                        mTimeoutStateIndicator = "starting write; updating values";
                        mStartWrite            = DateTime.Now;

                        mNumberOfWrites++;
                        if (mWriteRequestsInTagList.Count > mMaxValuesPerWrite)
                        {
                            mMaxValuesPerWrite = mWriteRequestsInTagList.Count;
                        }

                        //                    mProject.Window().logMessage(Name + " writing " + mWriteRequestsInTagList.Count + " values");
                        int result = -99911999;

                        short requestIndex = 0;
                        foreach (TNDWriteRequest req in mWriteRequestsInTagList)
                        {
                            //object valueToWrite = req.GetValueAsObject();
                            //axTndNTag.UpdatVariantValue(requestIndex, ref valueToWrite);
                            int valueToWrite = (int)req.GetValueAsLong();
                            axTndNTag.UpdateLongValue(requestIndex, valueToWrite);
                            //object valAsObject = valueToWrite;
                            //axTndNTag.UpdateVariantVal(requestIndex, ref valAsObject);
                            requestIndex++;
                        }

                        mTimeoutStateIndicator = "starting write";
                        mValuesUpdated         = DateTime.Now;
                        mValuesUpdate.NewPeriod(mStartWrite, mValuesUpdated);
                        try
                        {
                            result = axTndNTag.Write();
                        }
                        catch (COMException comException)
                        {
                            mProject.Window().logMessageWithFlush("ERROR: COM Exception during TND write attempt. code=" + comException.ErrorCode + "  msg=" + comException.Message);
                        }
                        catch (Exception exception)
                        {
                            mProject.Window().logMessageWithFlush("ERROR: Exception during TND write attempt. msg=" + exception.Message);
                        }
                        mValueSent = DateTime.Now;
                        mValueSending.NewPeriod(mValuesUpdated, mValueSent);

                        if (result == TNDLink.ThinkAndDoSuccess)
                        {
                            mTimeoutStateIndicator = "finished write successfully";
                            foreach (TNDWriteRequest req in mWriteRequestsInTagList)
                            {
                                if (req.IsOneTimeWrite())
                                {
                                    req.Active = false;
                                }
                            }
                            mRequestsCleanedUp = DateTime.Now;
                            mRequestCleanup.NewPeriod(mValueSent, mRequestsCleanedUp);
                        }
                        else
                        {
                            mTimeoutStateIndicator = "finished write WITH ERRORS";
                            if (result != lastResult)
                            {
                                mProject.Window().logMessage("ERROR: TND write failed for '" + Name + "': " + TNDLink.GetTNDResultMessage(result));
                            }
                            HandleLostConnection();
                        }
                        lastResult = result;
                        //                    mProject.Window().logMessage(Name + " finished writing");
                    }
                }
                catch (Exception e)
                {
                    mProject.Window().logMessage("ERROR: Exception in TND Writer " + Name + "; msg=" + e.Message);
                }
            }

            if (Connected)
            {
                mTimeoutStateIndicator = "restarting poll timer";
                mPollTimer.Enabled     = true;
            }
            mTimeoutStateIndicator = "poll completed";
            mTimeoutTimer.Enabled  = false;
        }
예제 #9
0
        public void HandleValue(object valueFromTND)
        {
            if (valueFromTND == null)
            {
                if (mTNDReader != null)
                {
                    mTNDReader.Project().Window().logMessageWithFlush("ERROR: TNDReadRequest.HandleValue() called with value=null");
                }
                return;
            }
            bool noticedListener = false;

            using (TimedLock.Lock(listenerLock))
            {
                if (BoolValueReceived != null)
                {
                    noticedListener = true;
                    switch (mTNDDataType)
                    {
                    case TNDLink.TNDDataTypeEnum.Input:
                        goto case TNDLink.TNDDataTypeEnum.Flag;

                    case TNDLink.TNDDataTypeEnum.Output:
                        goto case TNDLink.TNDDataTypeEnum.Flag;

                    case TNDLink.TNDDataTypeEnum.Flag:
                        BoolValueReceived((bool)valueFromTND);
                        break;

                    case TNDLink.TNDDataTypeEnum.Counter:
                        goto case TNDLink.TNDDataTypeEnum.Number;

                    case TNDLink.TNDDataTypeEnum.Number:
                        BoolValueReceived(((int)valueFromTND) == 0 ? false : true);
                        break;

                    default:
                        throw new ArgumentException("Conversion from TND type " + mTNDDataType + " to Boolean is not supported");
                    }
                }
                if (WholeNumberReceived != null)
                {
                    noticedListener = true;
                    switch (mTNDDataType)
                    {
                    case TNDLink.TNDDataTypeEnum.Input:
                        goto case TNDLink.TNDDataTypeEnum.Flag;

                    case TNDLink.TNDDataTypeEnum.Output:
                        goto case TNDLink.TNDDataTypeEnum.Flag;

                    case TNDLink.TNDDataTypeEnum.Flag:
                        WholeNumberReceived(((bool)valueFromTND) ? 1 : 0);
                        break;

                    case TNDLink.TNDDataTypeEnum.Counter:
                        goto case TNDLink.TNDDataTypeEnum.Number;

                    case TNDLink.TNDDataTypeEnum.Number:
                        WholeNumberReceived((int)valueFromTND);
                        break;

                    default:
                        throw new ArgumentException("Conversion from TND type " + mTNDDataType + " to Whole Number is not supported");
                    }
                }
                if (DecimalNumberReceived != null)
                {
                    noticedListener = true;
                    switch (mTNDDataType)
                    {
                    case TNDLink.TNDDataTypeEnum.Float:
                        DecimalNumberReceived((float)valueFromTND);
                        break;

                    case TNDLink.TNDDataTypeEnum.Input:
                        goto case TNDLink.TNDDataTypeEnum.Flag;

                    case TNDLink.TNDDataTypeEnum.Output:
                        goto case TNDLink.TNDDataTypeEnum.Flag;

                    case TNDLink.TNDDataTypeEnum.Flag:
                        DecimalNumberReceived(((bool)valueFromTND) ? 1 : 0);
                        break;

                    case TNDLink.TNDDataTypeEnum.Counter:
                        goto case TNDLink.TNDDataTypeEnum.Number;

                    case TNDLink.TNDDataTypeEnum.Number:
                        DecimalNumberReceived((int)valueFromTND);
                        break;

                    default:
                        throw new ArgumentException("Conversion from TND type " + mTNDDataType + " to Decimal Number is not supported");
                    }
                }
                if (!PermanentRequest && !noticedListener)
                {
                    Active = false; // I want this within the lock since its implementation verifes that the listeners are all empty, and I don't ever want it to throw an exception
                }
            } // end of lock
        }