From 9151dfa720aeac578fa8defc67717a00ea9860b8 Mon Sep 17 00:00:00 2001 From: edevoogd Date: Sun, 21 Feb 2021 03:58:22 +0100 Subject: [PATCH 1/3] Implement IAsyncDisposable/IDisposable --- src/ClockQuantization.csproj | 4 ++- src/ClockQuantization.xml | 12 ++++++++ src/ClockQuantizer.cs | 59 ++++++++++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/ClockQuantization.csproj b/src/ClockQuantization.csproj index 9faf376..a3ec1e7 100644 --- a/src/ClockQuantization.csproj +++ b/src/ClockQuantization.csproj @@ -1,4 +1,4 @@ - + Library @@ -13,7 +13,9 @@ + + \ No newline at end of file diff --git a/src/ClockQuantization.xml b/src/ClockQuantization.xml index 8a7d5f0..aca3ac3 100644 --- a/src/ClockQuantization.xml +++ b/src/ClockQuantization.xml @@ -163,6 +163,18 @@ the will pick up on external events, instead of relying on an internal metronome. + + + + + + + + + + + + Represents an interval within a 's temporal context. diff --git a/src/ClockQuantizer.cs b/src/ClockQuantizer.cs index 099696b..aabd155 100644 --- a/src/ClockQuantizer.cs +++ b/src/ClockQuantizer.cs @@ -1,5 +1,6 @@ using System; using System.Runtime.CompilerServices; +using System.Threading.Tasks; namespace ClockQuantization { @@ -9,11 +10,11 @@ namespace ClockQuantization /// calls, as well as by and events. /// /// Under certain conditions, an advance operation may be incurred by calls. - public class ClockQuantizer //: IAsyncDisposable, IDisposable + public class ClockQuantizer : IAsyncDisposable, IDisposable { private readonly ISystemClock _clock; private Interval? _currentInterval; - private readonly System.Threading.Timer? _metronome; + private System.Threading.Timer? _metronome; #region Fields & properties @@ -320,5 +321,59 @@ private Interval CommitAdvance(AdvancePreparationInfo preparation) private void Context_MetronomeTicked(object? _, EventArgs __) => Advance(metronomic: true); private void Context_ClockAdjusted(object? _, EventArgs __) => Advance(metronomic: false); + + #region IAsyncDisposable/IDisposable + + /// + public void Dispose() + { + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + + /// + public async ValueTask DisposeAsync() + { + await DisposeAsyncCore(); + + Dispose(disposing: false); + GC.SuppressFinalize(this); + } + + /// + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + _metronome?.Dispose(); + } + + _metronome = null; + } + + /// + protected virtual async ValueTask DisposeAsyncCore() + { +#if NETSTANDARD2_1 || NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0 || NET5_0_OR_GREATER + if (_metronome is IAsyncDisposable asyncDisposable) + { + await asyncDisposable.DisposeAsync().ConfigureAwait(false); + } + else + { + _metronome?.Dispose(); + } +#else + if (_metronome is not null) + { + await default(ValueTask).ConfigureAwait(false); + _metronome.Dispose(); + } +#endif + + _metronome = null; + } + + #endregion } } \ No newline at end of file From 436a7cdb3044d126f1993912d77efe965256fb06 Mon Sep 17 00:00:00 2001 From: edevoogd Date: Sun, 21 Feb 2021 04:16:43 +0100 Subject: [PATCH 2/3] More readable flow of DisposeAsyncCore() between TFMs? --- src/ClockQuantizer.cs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/ClockQuantizer.cs b/src/ClockQuantizer.cs index aabd155..dcaffd8 100644 --- a/src/ClockQuantizer.cs +++ b/src/ClockQuantizer.cs @@ -354,26 +354,30 @@ protected virtual void Dispose(bool disposing) /// protected virtual async ValueTask DisposeAsyncCore() { + if (_metronome is null) + { + goto done; + } + #if NETSTANDARD2_1 || NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0 || NET5_0_OR_GREATER if (_metronome is IAsyncDisposable asyncDisposable) { await asyncDisposable.DisposeAsync().ConfigureAwait(false); - } - else - { - _metronome?.Dispose(); + goto finish; } #else - if (_metronome is not null) - { - await default(ValueTask).ConfigureAwait(false); - _metronome.Dispose(); - } + await default(ValueTask).ConfigureAwait(false); #endif + _metronome!.Dispose(); +#if NETSTANDARD2_1 || NETCOREAPP3_0 || NETCOREAPP3_1 || NET5_0 || NET5_0_OR_GREATER +finish: +#endif _metronome = null; +done: + ; } - #endregion +#endregion } -} \ No newline at end of file +} From b87b5f2e0870f72042f0e58b28dcef9f550e463e Mon Sep 17 00:00:00 2001 From: edevoogd Date: Sun, 21 Feb 2021 04:23:27 +0100 Subject: [PATCH 3/3] Update readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index b189d7c..c24162f 100644 --- a/readme.md +++ b/readme.md @@ -69,5 +69,5 @@ Local experimentation shows further advantage to using `Environment.TickCount64` 2. Document the idea behind `ISystemClockTemporalContext`, without actually writing documentation # Remaining work -- [ ] Implement `IDisposable` and/or `IAsyncDisposable` on `ClockQuantizer` +- [X] Implement `IDisposable` and/or `IAsyncDisposable` on `ClockQuantizer` → [#6](https://github.com/edevoogd/ClockQuantization/pull/6) - [ ] Integrate this proposal in a [local fork](https://github.com/edevoogd/runtime) of Microsoft.Extensions.Caching.Memory as a PoC