C# / CHAPTER 14
Deterministic cleanup with using
AdvancedTie resource lifetime to the scope that owns it.
By the end of this chapter
- Use IDisposable correctly
- Distinguish cleanup from rollback
- Avoid returning disposed resources
The idea
Some objects own resources that need timely cleanup, such as file handles. IDisposable exposes Dispose, and a using statement arranges disposal when control leaves its scope, including ordinary exception paths. This is separate from garbage collection: unreachable managed memory and an external resource’s usable lifetime are different concerns.
A using declaration disposes its resource at the end of the containing scope, not immediately after its last apparent use. A nested using block can make an earlier lifetime boundary explicit. Do not return a resource that has already been disposed by a local using. Also distinguish cleanup from rollback: disposing a stream does not undo data it already wrote, and a resource operation can still throw.
using System;
using (var resource = new Marker()) {
Console.WriteLine("work");
}
Console.WriteLine("after");
sealed class Marker : IDisposable {
public void Dispose() => Console.WriteLine("dispose");
}work dispose after
Leaving the using block calls Dispose before the subsequent statement.
Try it yourself
Refactor two sequential resource operations so the first resource is disposed before the second is opened.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
CHECK YOUR UNDERSTANDING