Fix Flip Mode - ver. 3.9.3141.0
Add robust handling for form closure in UNI Data Entry: prevent operations on disposed/closing forms, enhance logging, and update logic in serial number and volume updates. Increment version to 3.9.3141.0.
This commit is contained in:
parent
f34046df2a
commit
b904d0ca41
@ -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")]
|
||||
|
||||
@ -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<SerialNumberReadEventArgs> 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 ? "<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 ? "<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<IRegReader> 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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user