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; } } }
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; } } }
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; }