fix(adminui): guard Alerts chip auto-clear against stale-timer race (review)
This commit is contained in:
@@ -135,6 +135,7 @@ else
|
|||||||
// Auto-clear timer for the per-row result chip (mirrors DriverStatusPanel): the chip is set in
|
// Auto-clear timer for the per-row result chip (mirrors DriverStatusPanel): the chip is set in
|
||||||
// ShowOpResult and cleared 8 s later so it doesn't persist until the next action.
|
// ShowOpResult and cleared 8 s later so it doesn't persist until the next action.
|
||||||
private System.Threading.Timer? _opResultClearTimer;
|
private System.Threading.Timer? _opResultClearTimer;
|
||||||
|
private object? _opResultClearToken;
|
||||||
|
|
||||||
// Per-row timed-shelve duration (minutes). Keyed by AlarmId so each row's number input is
|
// Per-row timed-shelve duration (minutes). Keyed by AlarmId so each row's number input is
|
||||||
// independent — binding every row to one shared field would couple all the inputs together.
|
// independent — binding every row to one shared field would couple all the inputs together.
|
||||||
@@ -240,13 +241,20 @@ else
|
|||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
// Auto-clear the result chip after 8 s (mirrors DriverStatusPanel). System.Threading.Timer
|
// Auto-clear the result chip after 8 s (mirrors DriverStatusPanel). System.Threading.Timer
|
||||||
// is used (not System.Timers.Timer) so DisposeAsync can drain any in-flight callback.
|
// is used (not System.Timers.Timer) so DisposeAsync can drain any in-flight callback.
|
||||||
|
var token = _opResultClearToken = new object();
|
||||||
_opResultClearTimer?.Dispose();
|
_opResultClearTimer?.Dispose();
|
||||||
_opResultClearTimer = new System.Threading.Timer(_ =>
|
_opResultClearTimer = new System.Threading.Timer(_ =>
|
||||||
{
|
InvokeAsync(() =>
|
||||||
_opResultMessage = null;
|
{
|
||||||
_opResultAlarmId = "";
|
// Ignore a stale fire: a newer action superseded this timer's chip. (Timer.Dispose does
|
||||||
InvokeAsync(StateHasChanged);
|
// not drain an already-queued callback, so without this a stale timer could clear a
|
||||||
}, null, TimeSpan.FromSeconds(8), Timeout.InfiniteTimeSpan);
|
// freshly-set result from a different row.)
|
||||||
|
if (!ReferenceEquals(_opResultClearToken, token)) return;
|
||||||
|
_opResultMessage = null;
|
||||||
|
_opResultAlarmId = "";
|
||||||
|
StateHasChanged();
|
||||||
|
}),
|
||||||
|
null, TimeSpan.FromSeconds(8), Timeout.InfiniteTimeSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAlarm(AlarmTransitionEvent evt) =>
|
private void OnAlarm(AlarmTransitionEvent evt) =>
|
||||||
|
|||||||
Reference in New Issue
Block a user