public void RemoveWriteRequest(TNDWriteRequest theRequest) { // lock (masterListLock) using (TimedLock.Lock(masterListLock)) { mWriteRequests_all.Remove(theRequest); if (theRequest.Active) { mTagListDirty = true; } } }
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 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); }
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); }
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; } } }
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; }
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; }
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 }