C# / CHAPTER 14

Deterministic cleanup with using

Advanced

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

C# example
using System;
using (var resource = new Marker()) {
  Console.WriteLine("work");
}
Console.WriteLine("after");
sealed class Marker : IDisposable {
  public void Dispose() => Console.WriteLine("dispose");
}
Result
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

Chapter checkpoint

What does using primarily guarantee for a successfully acquired IDisposable resource?