diff --git a/src/Foundatio/Utility/AsyncDisposableAction.cs b/src/Foundatio/Utility/AsyncDisposableAction.cs new file mode 100644 index 00000000..cefa2d0f --- /dev/null +++ b/src/Foundatio/Utility/AsyncDisposableAction.cs @@ -0,0 +1,32 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Foundatio.Utility; + +/// +/// A class that will call an when Disposed. +/// +public sealed class AsyncDisposableAction : IAsyncDisposable +{ + private Func _exitTask; + + /// + /// Initializes a new instance of the class. + /// + /// The exit action. + public AsyncDisposableAction(Func exitTask) + { + _exitTask = exitTask; + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + async ValueTask IAsyncDisposable.DisposeAsync() + { + var exitAction = Interlocked.Exchange(ref _exitTask, null); + if (exitAction is not null) + await _exitTask().AnyContext(); + } +} diff --git a/src/Foundatio/Utility/DisposableAction.cs b/src/Foundatio/Utility/DisposableAction.cs index fe6f1bd4..aea8bd95 100644 --- a/src/Foundatio/Utility/DisposableAction.cs +++ b/src/Foundatio/Utility/DisposableAction.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; namespace Foundatio.Utility; @@ -7,8 +8,7 @@ namespace Foundatio.Utility; /// public sealed class DisposableAction : IDisposable { - private readonly Action _exitAction; - private bool _disposed; + private Action _exitAction; /// /// Initializes a new instance of the class. @@ -24,10 +24,7 @@ public DisposableAction(Action exitAction) /// void IDisposable.Dispose() { - if (_disposed) - return; - - _exitAction(); - _disposed = true; + var exitAction = Interlocked.Exchange(ref _exitAction, null); + exitAction?.Invoke(); } }