Usage
The Lifetime
class looks like this:
Your code receives a Lifetime
instance, and registers its cleanup callback using AddAction
. It then doesn't need to do anything else. When the Lifetime
is terminated, the callback is called, and the action is performed. Actions are called in reverse order to how they were added. If an exception is thrown by an action, it is logged, and the next action is called.
The
AddBracket
method accepts two callbacks. The first,fOpening
, is called immediately, and the second,fClosing
is registered to run when theLifetime
is terminated. This way, the methods form a "bracket" around the duration of theLifetime
object.There is also a bridge between
IDisposable
andLifetime
. TheAddDispose
method simply registers a callback that will callDispose
on the givenIDisposable
.The
AddRef
method keeps a given object alive (i.e. it won't be garbage collected) until theLifetime
is terminated.You can check to see if a
Lifetime
has been terminated by calling theIsTerminated
property. Note that you can't terminate aLifetime
directly.
Extension methods
Generally speaking, especially when writing plugins, you are more likely to pass a Lifetime
to a method than to directly add your own cleanup callbacks. When consuming services, adding items or registering callbacks, passing in a Lifetime
will allow that service or object to add the cleanup, removal or un-registration code for you. You should generally favour method overloads that take a Lifetime
over those that don't.
For example, the JetBrains.Util.CollectionUtil
class provides several extension methods for ICollection<T>
. These methods simply call Lifetime.AddBracket
to immediately add the item, and will remove the item when the Lifetime
is terminated. This means the items only exist in the collection for the duration of the Lifetime
.
Similarly, the Threading
subsystem's JetDispatcher
class, which can be used to dispatch actions to the main thread has an overload to the BeginInvoke
method which take a Lifetime
. This queues the given action to execute on the main thread, at some point in the near future. If you terminate the Lifetime
, the action is (effectively) removed from the queue, and the action isn't executed. This is an easy way to prevent race conditions.