diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs index 7307fe62f..f039b9bd9 100644 --- a/TBF/Properties/AssemblyInfo.cs +++ b/TBF/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("3.9.3140.0")] -[assembly: AssemblyFileVersion("3.9.3140.0")] +[assembly: AssemblyVersion("3.9.3141.0")] +[assembly: AssemblyFileVersion("3.9.3141.0")] diff --git a/TBF/Rig/DataEntry/Uni/CycleBgEnForm.cs b/TBF/Rig/DataEntry/Uni/CycleBgEnForm.cs index eb1966c77..7bcd0e48a 100644 --- a/TBF/Rig/DataEntry/Uni/CycleBgEnForm.cs +++ b/TBF/Rig/DataEntry/Uni/CycleBgEnForm.cs @@ -76,6 +76,7 @@ namespace TBF.Rig.DataEntry.Uni /// Set to 'true' when the form closes public bool Completed { get { return completed; } } bool completed; + private volatile bool isClosing; private System.Windows.Forms.Timer autoCloseTimer; private int autoCloseSecondsRemaining; private string okButtonTextBeforeAutoClose; @@ -852,6 +853,12 @@ namespace TBF.Rig.DataEntry.Uni private void UpdateSomethingBySerial(IRegReader eReader, string eSerialNumber) { + if (!CanUpdateDataEntryUi()) + { + log.Debug("DATA_ENTRY_SERIAL_UPDATE_SKIPPED Form is closing or disposed."); + return; + } + log.Debug($"RegReader name: {eReader.Name}, Serial No updated: " + eSerialNumber); PopulateComboBoxWithSerialNumbers(eReader, eSerialNumber); } @@ -910,6 +917,12 @@ namespace TBF.Rig.DataEntry.Uni } private void DoneUpdate() { + if (!CanUpdateDataEntryUi()) + { + log.Debug("DATA_ENTRY_SERIAL_DONE_SKIPPED Form is closing or disposed."); + return; + } + log.Debug("DoneUpdate"); //enbale only found checkboxes @@ -998,12 +1011,15 @@ namespace TBF.Rig.DataEntry.Uni private void SetSerialNumberWatermark(IRegReader reader, string watermark) { - if (reader == null || regReaders == null || comboBoxes == null) + if (reader == null || regReaders == null || comboBoxes == null || + !CanUpdateDataEntryUi()) return; - if (IsHandleCreated && InvokeRequired) + if (InvokeRequired) { - BeginInvoke(new Action(() => SetSerialNumberWatermark(reader, watermark))); + TryBeginDataEntryInvoke( + () => SetSerialNumberWatermark(reader, watermark), + "serial-number watermark"); return; } @@ -1176,6 +1192,15 @@ namespace TBF.Rig.DataEntry.Uni Close(); } + protected override void OnFormClosing(FormClosingEventArgs e) + { + isClosing = true; + StopAutoCloseCountdown(); + SerialNumberRead = null; + DoneUpdateBySerial = null; + base.OnFormClosing(e); + } + #endregion public event EventHandler SerialNumberRead; @@ -1211,39 +1236,93 @@ namespace TBF.Rig.DataEntry.Uni IsHandleCreated, InvokeRequired, System.Threading.Thread.CurrentThread.ManagedThreadId); var handler = SerialNumberRead; // copy for thread-safety - if (handler == null) return; - if (IsHandleCreated && InvokeRequired) + if (handler == null || !CanUpdateDataEntryUi()) { - BeginInvoke(new Action(() => - { - log.DebugFormat( - "DATA_ENTRY_SERIAL_EVENT_DISPATCH Name={0}, Position={1}, Thread={2}", - reader == null ? "" : reader.Name, - reader == null ? -1 : reader.Position, - System.Threading.Thread.CurrentThread.ManagedThreadId); - handler(this, new SerialNumberReadEventArgs(reader, serial)); - })); + log.Debug("DATA_ENTRY_SERIAL_EVENT_SKIPPED Form is closing or disposed."); + return; } - else + + Action dispatch = () => { + if (!CanUpdateDataEntryUi()) + { + log.Debug("DATA_ENTRY_SERIAL_EVENT_DISPATCH_SKIPPED Form closed before dispatch."); + return; + } + + log.DebugFormat( + "DATA_ENTRY_SERIAL_EVENT_DISPATCH Name={0}, Position={1}, Thread={2}", + reader == null ? "" : reader.Name, + reader == null ? -1 : reader.Position, + System.Threading.Thread.CurrentThread.ManagedThreadId); handler(this, new SerialNumberReadEventArgs(reader, serial)); + }; + + if (InvokeRequired) + { + TryBeginDataEntryInvoke(dispatch, "serial-number result"); + return; + } + + dispatch(); + } + + private bool CanUpdateDataEntryUi() + { + return !isClosing && !IsDisposed && !Disposing; + } + + private void TryBeginDataEntryInvoke(Action action, string operation) + { + if (!CanUpdateDataEntryUi() || !IsHandleCreated) + return; + + try + { + BeginInvoke(action); + } + catch (ObjectDisposedException) + { + log.DebugFormat( + "DATA_ENTRY_SERIAL_INVOKE_SKIPPED Operation={0}, Reason=disposed", + operation); + } + catch (InvalidOperationException ex) + { + log.DebugFormat( + "DATA_ENTRY_SERIAL_INVOKE_SKIPPED Operation={0}, Reason={1}", + operation, + ex.Message); } } protected virtual void OnReadDone() { var handler = DoneUpdateBySerial; // copy for thread-safety - if (handler == null) return; - - if (IsHandleCreated && InvokeRequired) + if (handler == null || !CanUpdateDataEntryUi()) { - BeginInvoke(new Action(() => - handler(this, new SerialNumberReadDoneEventArgs()))); + log.Debug("DATA_ENTRY_SERIAL_DONE_EVENT_SKIPPED Form is closing or disposed."); + return; } - else + + Action dispatch = () => { + if (!CanUpdateDataEntryUi()) + { + log.Debug("DATA_ENTRY_SERIAL_DONE_DISPATCH_SKIPPED Form closed before dispatch."); + return; + } + handler(this, new SerialNumberReadDoneEventArgs()); + }; + + if (InvokeRequired) + { + TryBeginDataEntryInvoke(dispatch, "serial-number completion"); + return; } + + dispatch(); } public async void ReadSerialNumbersAsync(IEnumerable regReaders) @@ -1305,6 +1384,12 @@ namespace TBF.Rig.DataEntry.Uni var results = await Task.WhenAll(tasks).ConfigureAwait(false); + if (isClosing) + { + log.Debug("DATA_ENTRY_SERIAL_RESULTS_SKIPPED Form was closed while reading."); + return; + } + foreach (var kv in results) { var reader = kv.Key; diff --git a/TBF/Rig/DataEntry/Uni/TestStartEndForm.cs b/TBF/Rig/DataEntry/Uni/TestStartEndForm.cs index 246dd3906..4959a1077 100644 --- a/TBF/Rig/DataEntry/Uni/TestStartEndForm.cs +++ b/TBF/Rig/DataEntry/Uni/TestStartEndForm.cs @@ -126,6 +126,7 @@ namespace TBF.Rig.DataEntry.Uni /// Set to 'true' when the form closes public bool Completed { get { return completed; } } bool completed; + private volatile bool isClosing; private System.Windows.Forms.Timer autoCloseTimer; private int autoCloseSecondsRemaining; private string okButtonTextBeforeAutoClose; @@ -476,6 +477,15 @@ namespace TBF.Rig.DataEntry.Uni } } + protected override void OnFormClosing(FormClosingEventArgs e) + { + isClosing = true; + StopAutoCloseCountdown(); + VolumeStartReadbyRegReader = null; + DoneUpdateByRegReader = null; + base.OnFormClosing(e); + } + void Localize() { okButton.Text = Strings.OkBtnText; @@ -669,6 +679,12 @@ namespace TBF.Rig.DataEntry.Uni private void DoneUpdate() { + if (!CanUpdateDataEntryUi()) + { + log.Debug("DATA_ENTRY_VOLUME_DONE_SKIPPED Form is closing or disposed."); + return; + } + log.Debug("DoneUpdate"); this.okButton.Enabled = GetStoredOrDefault("okButton"); this.largeTextBox.Enabled = GetStoredOrDefault("largeTextBox"); @@ -687,6 +703,12 @@ namespace TBF.Rig.DataEntry.Uni public void UpdateVolume(IRegReader eArgsReader, double eArgsVolume) { + if (!CanUpdateDataEntryUi()) + { + log.Debug("DATA_ENTRY_VOLUME_UPDATE_SKIPPED Form is closing or disposed."); + return; + } + log.DebugFormat( "DATA_ENTRY_VOLUME_UI_HANDLER Name={0}, Position={1}, DebugLevel={2}, Volume={3}, IsNaN={4}", eArgsReader.Name, eArgsReader.Position, eArgsReader.DebugLevel, @@ -1584,31 +1606,87 @@ namespace TBF.Rig.DataEntry.Uni protected virtual void OnReadVolume(IRegReader reader, double volume) { var handler = VolumeStartReadbyRegReader; // copy for thread-safety - if (handler == null) return; - if (IsHandleCreated && InvokeRequired) + if (handler == null || !CanUpdateDataEntryUi()) { - BeginInvoke(new Action(() => - handler(this, new VolumeReadEventArgs(reader, volume)))); + log.Debug("DATA_ENTRY_VOLUME_EVENT_SKIPPED Form is closing or disposed."); + return; } - else + + Action dispatch = () => { + if (!CanUpdateDataEntryUi()) + { + log.Debug("DATA_ENTRY_VOLUME_EVENT_DISPATCH_SKIPPED Form closed before dispatch."); + return; + } + handler(this, new VolumeReadEventArgs(reader, volume)); + }; + + if (InvokeRequired) + { + TryBeginDataEntryInvoke(dispatch, "volume result"); + return; } + + dispatch(); } protected virtual void OnReadDone() { var handler = DoneUpdateByRegReader; // copy for thread-safety - if (handler == null) return; - - if (IsHandleCreated && InvokeRequired) + if (handler == null || !CanUpdateDataEntryUi()) { - BeginInvoke(new Action(() => - handler(this, new VolumeReadDoneEventArgs()))); + log.Debug("DATA_ENTRY_VOLUME_DONE_EVENT_SKIPPED Form is closing or disposed."); + return; } - else + + Action dispatch = () => { + if (!CanUpdateDataEntryUi()) + { + log.Debug("DATA_ENTRY_VOLUME_DONE_DISPATCH_SKIPPED Form closed before dispatch."); + return; + } + handler(this, new VolumeReadDoneEventArgs()); + }; + + if (InvokeRequired) + { + TryBeginDataEntryInvoke(dispatch, "volume completion"); + return; + } + + dispatch(); + } + + private bool CanUpdateDataEntryUi() + { + return !isClosing && !IsDisposed && !Disposing; + } + + private void TryBeginDataEntryInvoke(Action action, string operation) + { + if (!CanUpdateDataEntryUi() || !IsHandleCreated) + return; + + try + { + BeginInvoke(action); + } + catch (ObjectDisposedException) + { + log.DebugFormat( + "DATA_ENTRY_VOLUME_INVOKE_SKIPPED Operation={0}, Reason=disposed", + operation); + } + catch (InvalidOperationException ex) + { + log.DebugFormat( + "DATA_ENTRY_VOLUME_INVOKE_SKIPPED Operation={0}, Reason={1}", + operation, + ex.Message); } } @@ -1663,6 +1741,12 @@ namespace TBF.Rig.DataEntry.Uni var results = await Task.WhenAll(tasks).ConfigureAwait(false); + if (isClosing) + { + log.Debug("DATA_ENTRY_VOLUME_RESULTS_SKIPPED Form was closed while reading."); + return; + } + foreach (var kv in results) { var reader = kv.Key; diff --git a/TBF/Rig/TestMethods/StandingStartMassCollection/StandingStartMassCollectionSeq.cs b/TBF/Rig/TestMethods/StandingStartMassCollection/StandingStartMassCollectionSeq.cs index cc65dea54..a7143bbb1 100644 --- a/TBF/Rig/TestMethods/StandingStartMassCollection/StandingStartMassCollectionSeq.cs +++ b/TBF/Rig/TestMethods/StandingStartMassCollection/StandingStartMassCollectionSeq.cs @@ -1321,6 +1321,9 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection Results.Entities.MeterTestRslt meterRslt = BatchRslts.GetMeterTestRslt(testName, i, Common.CompoundMeterId.Single); GenericDevices.IRegReader regReader = sensPath.RegisterReaders[i]; +#if IPERL + TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead; +#endif if (meterRslt != null && regReader != null) { @@ -1404,6 +1407,15 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection { meterRslt.WaterMeter.SerialNr = regReaderCommon.SerialNr; } + +#if IPERL + if (iPerl != null) + { + meterRslt.FlipMode = iPerl.ConfigStruct != null && iPerl.ConfigStruct.FlipMode.HasValue + ? (int?)iPerl.ConfigStruct.FlipMode.Value + : null; + } +#endif } }