diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs index 3f60a1cd7ff7c..42b9dd61f5328 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/CancellationTokenSource.cs @@ -350,19 +350,7 @@ private void CancelAfter(uint millisecondsDelay) } } - // It is possible that _timer has already been disposed, so we must do - // the following in a try/catch block. - try - { - timer.Change(millisecondsDelay, Timeout.UnsignedInfinite); - } - catch (ObjectDisposedException) - { - // Just eat the exception. There is no other way to tell that - // the timer has been disposed, and even if there were, there - // would not be a good way to deal with the observe/dispose - // race condition. - } + timer.Change(millisecondsDelay, Timeout.UnsignedInfinite, throwIfDisposed: false); } /// @@ -392,24 +380,13 @@ public bool TryReset() // to transition from canceled to non-canceled. if (_state == NotCanceledState) { - bool reset = false; - - try - { - // If there is no timer, then we're free to reset. If there is a timer, then we need to first try - // to reset it to be infinite so that it won't fire, and then recognize that it could have already - // fired by the time we successfully changed it, and so check to see whether that's possibly the case. - // If we successfully reset it and it never fired, then we can be sure it won't trigger cancellation. - reset = _timer is not TimerQueueTimer timer || - (timer.Change(Timeout.UnsignedInfinite, Timeout.UnsignedInfinite) && !timer._everQueued); - } - catch (ObjectDisposedException) - { - // Just eat the exception. There is no other way to tell that - // the timer has been disposed, and even if there were, there - // would not be a good way to deal with the observe/dispose - // race condition. - } + // If there is no timer, then we're free to reset. If there is a timer, then we need to first try + // to reset it to be infinite so that it won't fire, and then recognize that it could have already + // fired by the time we successfully changed it, and so check to see whether that's possibly the case. + // If we successfully reset it and it never fired, then we can be sure it won't trigger cancellation. + bool reset = + _timer is not TimerQueueTimer timer || + (timer.Change(Timeout.UnsignedInfinite, Timeout.UnsignedInfinite, throwIfDisposed: false) && !timer._everQueued); if (reset) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs index 6b7e928cd5ba3..108034d778d42 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Threading/Timer.cs @@ -515,14 +515,14 @@ internal string DisplayString } } - internal bool Change(uint dueTime, uint period) + internal bool Change(uint dueTime, uint period, bool throwIfDisposed = true) { bool success; lock (_associatedTimerQueue) { if (_canceled) - throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic); + return throwIfDisposed ? throw new ObjectDisposedException(null, SR.ObjectDisposed_Generic) : false; _period = period;