From bbfbd0f6d746ecdaec9c85110e513e5ab054ebdb Mon Sep 17 00:00:00 2001 From: David Leek Date: Tue, 3 Sep 2024 10:42:28 +0200 Subject: [PATCH] chore: use method signature overloads instead of dynamic in scheduler (#238) --- src/Unleash/Internal/UnleashExtensions.cs | 32 ++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/Unleash/Internal/UnleashExtensions.cs b/src/Unleash/Internal/UnleashExtensions.cs index 44db4d76..6dd9af98 100644 --- a/src/Unleash/Internal/UnleashExtensions.cs +++ b/src/Unleash/Internal/UnleashExtensions.cs @@ -32,14 +32,34 @@ internal static string ConvertToString(this Stream stream) } } - internal static void SafeTimerChange(this Timer timer, dynamic dueTime, dynamic period, ref bool disposeEnded) + internal static void SafeTimerChange(this Timer timer, int dueTime, int period, ref bool disposeEnded) { - if (dueTime.GetType() != period.GetType()) - throw new Exception("Data types has to match. (Int32 or TimeSpan)"); - - if (!(dueTime.GetType() != typeof(int) || dueTime.GetType() != typeof(TimeSpan))) - throw new Exception("Only System.Int32 or System.TimeSpan"); + try + { + timer?.Change(dueTime, period); + } + catch (ObjectDisposedException) + { + // race condition with Dispose can cause trigger to be called when underlying + // timer is being disposed - and a change will fail in this case. + // see + // https://msdn.microsoft.com/en-us/library/b97tkt95(v=vs.110).aspx#Anchor_2 + if (disposeEnded) + { + // we still want to throw the exception in case someone really tries + // to change the timer after disposal has finished + // of course there's a slight race condition here where we might not + // throw even though disposal is already done. + // since the offending code would most likely already be "failing" + // unreliably i personally can live with increasing the + // "unreliable failure" time-window slightly + throw; + } + } + } + internal static void SafeTimerChange(this Timer timer, TimeSpan dueTime, TimeSpan period, ref bool disposeEnded) + { try { timer?.Change(dueTime, period);