public void Dispose() { try { TimeoutCancelSource?.Cancel(); TimeoutCancelSource?.Dispose(); } catch { } }
public void UnlockAfter(TimeSpan unlockDelay) { if (TimeoutCancelSource == null || LockSemaphore.CurrentCount > 0) { return; // it's not unlockable because it's post-IDENTIFY or not locked } try { TimeoutCancelSource.Cancel(); TimeoutCancelSource.Dispose(); } catch { } TimeoutCancelSource = null; UnlockTask = Task.Delay(unlockDelay, CancellationToken.None); _ = UnlockTask.ContinueWith(InternalUnlock); }