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();
}
}