IDisposable

Description

interface Tinman.Core.System.IDisposable

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 a 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 LifecycleState.Created or LifecycleState.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.

A 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...
}

Public / Methods

Acquire​Base


[OwnerReturn] [Pure]
public method AcquireBase → ()

returns → IDisposable

The strong reference to this disposable object or null iff this object is no longer valid.

Acquires a strong reference to this disposable object.

The object will not be actually disposed by calls to Dispose when there is at least one strong reference left. Code that calls this method is responsible for calling the Dispose 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.

Acquire​Throw


[OwnerReturn] [Pure]
public method AcquireThrow → ()

returns → IDisposable

The strong reference to this disposable object.

Acquires a strong reference to this disposable object.

The object will not be actually disposed by calls to Dispose when there is at least one strong reference left. Code that calls this method is responsible for calling the Dispose method accordingly.

This method is not intended to be used in performance-critical code. It should only be used to high-level resource management.

TinmanException

If this object is no longer valid.

Dispose


[Dispose] [OwnerThis] [ThreadSafe]
public method Dispose → ()

Releases all resources held by this object if there are no more strong references to it, decrements the reference counter by one otherwise.

The Dispose method silently returns if the object has already been disposed.

Implementing methods must not throw any exceptions.

Public / Attributes

Is​Sole​Ownership


[ThreadSafe]
public attribute IsSoleOwnership → (get)

value : bool

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).

Will this object be disposed upon the next call to Dispose?