Nito.Disposables
2.5.0
Prefix Reserved
dotnet add package Nito.Disposables --version 2.5.0
NuGet\Install-Package Nito.Disposables -Version 2.5.0
<PackageReference Include="Nito.Disposables" Version="2.5.0" />
paket add Nito.Disposables --version 2.5.0
#r "nuget: Nito.Disposables, 2.5.0"
// Install Nito.Disposables as a Cake Addin #addin nuget:?package=Nito.Disposables&version=2.5.0 // Install Nito.Disposables as a Cake Tool #tool nuget:?package=Nito.Disposables&version=2.5.0
Disposables
IDisposable helper types.
Main Types
Disposable
/AsyncDisposable
- When disposed, invokes anAction
/Func<ValueTask>
.CollectionDisposable
/AsyncCollectionDisposable
- When disposed, disposes a collection of other disposables.IReferenceCountedDisposable<T>
- Maintains a reference count for a disposable and disposes it when the reference count reaches zero.NoopDisposable
- When disposed, does nothing.
Disposable and AsyncDisposable
The Disposable
type wraps an Action
, and invokes that Action
exactly once when it is disposed. The first thread to call Dispose
is the one that invokes the Action
; all other threads that call Dispose
are blocked until the Action
is completed. Once the Action
is completed, it is never invoked again; future calls to Disposable.Dispose
are no-ops.
You can create a Disposable
by calling Disposable.Create(Action)
or new Disposable(Action)
.
AsyncDisposable
is exactly the same as Disposable
except it wraps a Func<ValueTask>
.
You can call Abandon
to have the Disposable
/AsyncDisposable
abandon its disposal work and do nothing when it is disposed. Abandon
returns the Action
(or Func<ValueTask>
) that it would have taken on disposal; this can be passed to Create
to transfer ownership of the disposal actions.
If the Action
(or Func<Task>
) throws an exception, only the first caller of Dispose
(or DisposeAsync
) will observe the exception. All other calls to Dispose
/ DisposeAsync
will wait for the delegate to complete, but they will not observe the exception.
Advanced
You can append an Action
to a Disposable
by calling its Add
method with the Action
to add. When the Disposable
is disposed, it will call its actions in reverse order. When Add
is called, if the Disposable
is already disposed (or is in the process of being disposed by another thread), then the additional Action
is invoked immediately by the current thread after the disposal completes, and the other thread is not blocked waiting for the Action
to complete.
AsyncDisposable
may also have multiple delegates. By default, they are all invoked serially in reverse order, but you can change this to concurrent by creating the instance with the AsyncDisposeFlags.ExecuteConcurrently
flag.
CollectionDisposable
CollectionDisposable
contains a collection of IDisposable
instances, and disposes them all exactly once when it is disposed. The first thread to call Dispose
is the one that disposes all instances; all other threads that call Dispose
are blocked until all instances have been disposed. Once disposed, future calls to CollectionDisposable.Dispose
are no-ops.
You can create a CollectionDisposable
by calling CollectionDisposable.Create(...)
or new CollectionDisposable(...)
, passing the collection of disposables.
You can also append a disposable to the CollectionDisposable
by calling its Add
method and passing it the disposable. If the CollectionDisposable
is already disposed (or is in the process of being disposed by another thread), then the additional disposable is disposed immediately by the current thread after the disposal completes, and the other thread is not blocked waiting for the additional disposable to dispose.
AsyncCollectionDisposable
is exactly the same as CollectionDisposable
except it is a collection of IAsyncDisposable
instances. You can also create a mixed collection (containing both IDisposable
and IAsyncDisposable
instances) by calling ToAsyncDisposable
on your IDisposable
instances.
You can call Abandon
to have the CollectionDisposable
/AsyncCollectionDisposable
abandon its disposal work and do nothing when it is disposed. Abandon
returns the IEnumerable<IDisposable>
(or IEnumerable<IAsyncDisposable>
) that it would have disposed; this can be passed to Create
to transfer ownership of the disposal actions.
By default, all IAsyncDisposable
instances are disposed serially in reverse order, but you can change this to concurrent by creating the AsyncCollectionDisposable
instance with the AsyncDisposeFlags.ExecuteConcurrently
flag.
Fixing Other Disposables
CollectionDisposable
can be used as a wrapper to enforce only-dispose-once semantics on another disposable. If a type IncorrectDisposable
has a Dispose
method that breaks if it is called more than once, then CollectionDisposable.Create(incorrectDisposable)
returns an IDisposable
that will only invoke IncorrectDisposable.Dispose
a single time, regardless of how many times you call CollectionDisposable.Dispose
.
Reference Counted Disposables
You can create a reference-counted disposable wrapping a target disposable by passing the target disposable to ReferenceCountedDisposable.Create
. The reference-counted disposable represents an increment of the reference count, and decrements that reference count when disposed. When the reference count reaches zero, the target disposable is disposed.
You can increment the reference count by calling IReferenceCountedDisposable<T>.AddReference
, which returns an independent reference-counted disposable representing its own increment of the reference count.
A reference-counted disposable can access its underlying target disposable via IReferenceCountedDisposable<T>.Target
.
Advanced: Weak Reference Counted Disposables
You can create a weak-reference-counted disposable by calling IReferenceCountedDisposable<T>.AddWeakReference
. Weak-reference-counted disposables weakly reference the target disposable and the reference count. They do not represent an increment of the reference count.
You can attempt to increment the reference count for a weak-reference-counted disposable by calling IWeakReferenceCountedDisposable<T>.TryAddReference
. If successful, this method returns a (strong) reference-counted disposable.
You can also attempt to access the underlying target disposable via IWeakReferenceCountedDisposable<T>.TryGetTarget
.
Advanced: Custom Reference Counting
Reference-counted disposables by default use an ephemeron for the reference count, so calling ReferenceCountedDisposable.Create
multiple times on the same target disposable instance will share the underlying reference count. If the reference count is already be zero, this method will throw ObjectDisposedException
; to avoid this exception, you can call ReferenceCountedDisposable.TryCreate
.
If you want to use a new reference count and not use the ephemeron, you can call ReferenceCountedDisposable.CreateWithNewReferenceCounter
. This usage avoids ephemerons, which put pressure on the garbage collector.
NoopDisposable
A type implementing both IDisposable
and IAsyncDisposable
that does nothing when disposed.
You can retrieve the singleton instance via NoopDisposable.Instance
.
Advanced Types
SingleDisposable<T>
The SingleDisposable<T>
type is a base type for disposables that desire exactly-once semantics, blocking other threads calling Dispose
until the initial Dispose
is complete. Both Disposable
and CollectionDisposable
inherit from this type.
The type T
is an immutable type that represents the contextual state of the instance. It is initialized in the constructor, optionally updated by calling TryUpdateContext
, and finally retrieved and passed to Dispose(T)
exactly once when Dispose()
is called.
When the base type invokes Dispose(T)
, your derived type should perform whatever disposing logic it needs to.
AsyncSingleDisposable<T>
is exactly the same as SingleDisposable<T>
except that it implements IAsyncDisposable
instead of IDisposable
.
If Dispose(T)
(or DisposeAsync(T)
) throws an exception, only the first caller of Dispose
(or DisposeAsync
) will observe the exception. All other calls to Dispose
/ DisposeAsync
will wait for the delegate to complete, but they will not observe the exception.
SingleNonblockingDisposable<T>
The SingleNonblockingDisposable<T>
type is a base type for disposables that desire exactly-once semantics without blocking other threads calling Dispose
. It works exactly like SingleDisposable<T>
, except that once disposal has started, other threads calling Dispose
will return immediately, treating the additional Dispose
calls as a no-op.
AsyncSingleNonblockingDisposable<T>
is exactly the same as SingleNonblockingDisposable<T>
except that it implements IAsyncDisposable
instead of IDisposable
.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp1.0 was computed. netcoreapp1.1 was computed. netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard1.0 is compatible. netstandard1.1 was computed. netstandard1.2 was computed. netstandard1.3 was computed. netstandard1.4 was computed. netstandard1.5 was computed. netstandard1.6 was computed. netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net45 was computed. net451 was computed. net452 was computed. net46 was computed. net461 is compatible. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen30 was computed. tizen40 was computed. tizen60 was computed. |
Universal Windows Platform | uap was computed. uap10.0 was computed. |
Windows Phone | wp8 was computed. wp81 was computed. wpa81 was computed. |
Windows Store | netcore was computed. netcore45 was computed. netcore451 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.1
- System.Collections.Immutable (>= 1.5.0)
-
.NETStandard 1.0
- NETStandard.Library (>= 1.6.1)
- System.Collections.Immutable (>= 1.5.0)
- System.Dynamic.Runtime (>= 4.3.0)
-
.NETStandard 2.0
- System.Collections.Immutable (>= 1.5.0)
-
.NETStandard 2.1
- System.Collections.Immutable (>= 1.5.0)
-
net8.0
- System.Collections.Immutable (>= 1.5.0)
NuGet packages (29)
Showing the top 5 NuGet packages that depend on Nito.Disposables:
Package | Downloads |
---|---|
Nito.AsyncEx.Tasks
Common helper methods for tasks as used in asynchronous programming. |
|
Nito.Cancellation
Helper types for working with cancellation tokens and sources. |
|
Nito.Mvvm.Core
Basic helper types for MVVM applications. |
|
Nito.Mvvm.Async
Asynchronous helper types for MVVM applications. |
|
NINA.Astrometry
This assembly contains the astronomy components of N.I.N.A. |
GitHub repositories (17)
Showing the top 5 popular GitHub repositories that depend on Nito.Disposables:
Repository | Stars |
---|---|
StephenCleary/AsyncEx
A helper library for async/await.
|
|
microsoft/GraphEngine
Microsoft Graph Engine
|
|
laochiangx/ABP-ASP.NET-Boilerplate-Project-CMS
ABP module-zero +AdminLTE+Bootstrap Table+jQuery+Redis + sql server+quartz+hangfire权限管理系统
|
|
Kyrodan/KeeAnywhere
A cloud storage provider plugin for KeePass Password Safe
|
|
xamarin/Xamarin.Auth
Xamarin.Auth
|
Version | Downloads | Last updated |
---|---|---|
2.5.0 | 322,538 | 12/8/2023 |
2.5.0-alpha.2 | 185 | 12/3/2023 |
2.5.0-alpha.1 | 1,119 | 4/2/2023 |
2.4.0 | 231,568 | 3/3/2023 |
2.3.0 | 526,295 | 12/30/2021 |
2.3.0-pre02 | 1,197 | 12/28/2021 |
2.3.0-pre01 | 1,393 | 12/11/2021 |
2.2.1 | 50,082,298 | 9/25/2021 |
2.2.0 | 23,895,222 | 10/3/2020 |
2.2.0-pre01 | 4,147 | 6/9/2020 |
2.1.0 | 77,846 | 6/8/2020 |
2.1.0-pre03 | 1,373 | 6/7/2020 |
2.1.0-pre02 | 5,715 | 7/20/2019 |
2.1.0-pre01 | 1,677 | 5/29/2019 |
2.0.1 | 395,534 | 7/20/2019 |
2.0.0 | 31,776,912 | 6/2/2018 |
1.2.3 | 12,963,413 | 9/9/2017 |
1.2.2 | 1,915,060 | 8/26/2017 |
1.2.1 | 6,572 | 8/26/2017 |
1.2.0 | 2,720 | 8/23/2017 |
1.1.0 | 135,639 | 2/28/2017 |
1.1.0-alpha-02 | 1,899 | 1/27/2017 |
1.1.0-alpha-01 | 1,955 | 11/25/2016 |
1.0.0 | 7,957,598 | 8/16/2016 |