Base interface for classes whose objects hold resources (object references, GPU memory, file handles, monitors, etc.) and need to be disposed explicitly.
The following figure illustrates the state transitions an IDisposable object undergoes during its lifecycle (see LifecycleState):
## +--------------+ #### --------> | Created | ## ctor() +--------------+ | | Initialize() v +--------------+ | Initialized | +--------------+ | | Dispose() v +--------------+ | Disposing | +--------------+ ## | Disposed | --------> # # +--------------+ ~dtor() ##
After
instantiation,
the
object
is
either
in
state
Created
or
Initialized.
In
the
former
case,
the
object
must
be
initialized
by
calling
a
special
initialization
method,
which
is
usually
named
Initialize
.
In
the
latter
case,
initialization
is
not
necessary.
After
initialization,
the
object
is
in
state
Initialized
,
in
which
it
serves
its
purposes
and
can
be
used
without
limitations.
The
object
can
be
disposed
by
calling
the
Dispose
method.
Upon
disposal,
the
object
releases
all
held
resources
and
switches
to
state
Disposing/Disposed
.
Object
deletion
is
performed
automatically
after
disposal
(via
smart
pointers
in
C++,
via
garbage
collection
in
C#
and
Java).
If
an
object
is
deleted
without
having
been
disposed
before,
the
Dispose
method
is
invoked;
this
situation
should
be
avoided
in
C#
and
Java,
since
finalizer/destructor
calls
can
happen
at
any
time
and
from
within
any
thread.
An IDisposable object has an implicit ownership concept: The first owner of a disposable object is the code that has created it. From there, ownership transferal is indicated by use of the following code elements:
The constructor of a class implementing the IDisposable interface should look like the following (pseudo code):
ClassName() { // Initialize variables to NULL values here (applies to C++ only). try { // Constructor code here. } catch(<any exception>) { Dispose(); throw; } }This will ensure that all system resources allocated by constructor code will be released properly even if the constructor throws an exception, thereby leaving an incomplete object.
Since the Dispose method may be called on incomplete objects, the disposal code cannot assume that all resources have been allocated; instead every single resource must be checked if it is not NULL and then be disposed (pseudo code):
void Dispose() { if (resourceA != <null>) { // Release resourceA. resourceA = <null>; } if (resourceB != <null>) { // Release resourceB. resourceB = <null>; } // etc... }
Will this object be disposed upon the next call to Dispose?
[ThreadSafe]
|
||||
property
|
IsSoleOwnership
{
get
}
|
|||
type
|
bool
|
|||
value
|
true
if
the
object
will
be
disposed
when
Dispose
is
called,
false
if
the
object
will
not
be
disposed,
because
some
other
code
is
still
holding
shared
ownership
(see
AcquireThrow).
|
Returns the lifecycle state of this object.
property
|
LifecycleState
{
get
}
|
||
type
|
LifecycleState
|
||
value
|
The lifecycle state. | ||
inherited
|
ILifecycleState.LifecycleState
|
Acquires a strong reference to this disposable object.
[OwnerReturn, Pure]
|
||||
method
|
AcquireBase
()
|
|||
type
|
IDisposable
|
|||
returns
|
The
strong
reference
to
this
disposable
object
or
null
iff
this
object
is
no
longer
valid.
|
Remarks:
The object will not be actually disposed by calls to IDisposable when there is at least one strong reference left. Code that calls this method is responsible for calling the IDisposable method accordingly.
This method is not intended to be used in performance-critical code. It should only be used to high-level resource management.
Using this method usually requires type casting. Subclasses may additionally implement IDisposableGeneric, in order to provide some syntactic sugar for that.
Acquires a strong reference to this disposable object.
[OwnerReturn, Pure]
|
||||
method
|
AcquireThrow
()
|
|||
type
|
IDisposable
|
|||
returns
|
|
The strong reference to this disposable object. |
Remarks:
The object will not be actually disposed by calls to IDisposable when there is at least one strong reference left. Code that calls this method is responsible for calling the IDisposable method accordingly.
This method is not intended to be used in performance-critical code. It should only be used to high-level resource management.
Exceptions:
Releases all resources held by this object if there are no more strong references to it, decrements the reference counter by one otherwise.
[Dispose, OwnerThis, ThreadSafe]
|
||||
method
|
Dispose
()
|
Remarks:
The Dispose method silently returns if the object has already been disposed.
Implementing methods must not throw any exceptions.