<style> .reveal-up, .reveal-left, .reveal-right, .reveal-stagger > * { opacity: 1 !important; transform: none !important; } </style>
  1. Learn
  2. C#
  3. Advanced C#
All lessons in this course

Lesson 46 of 60 12 minAdvanced

IDisposable and using

Release files, connections and native resources at the right moment with Dispose and using, and implement IDisposable in your own classes.

The garbage collector manages memory. But some objects hold resources the GC knows nothing about: open files, database connections, network sockets, GPU buffers, native handles from libraries like VTK. These must be released as soon as you are done, not whenever the GC happens to run. That is the job of IDisposable.

IDisposable.cs
public interface IDisposable{    void Dispose();     // "release your resources now"}
Interactive

Is the file still locked?

Export.cs
using (var writer = new StreamWriter("report.csv")){    writer.WriteLine("Mark,Kg");    writer.WriteLine("B1,253");}   // writer.Dispose() runs here, ALWAYSConsole.WriteLine("Exported");
report.csvOPEN and locked: other programs can’t use it
Step 1 / 4
new StreamWriter opens the file and gets an operating-system handle. The file is locked while it is open.

The using statement

Using.cs
using (var conn = new SqlConnection(connectionString)){    conn.Open();    // … query …}   // conn.Dispose() is called here, even if an exception was thrown // C# 8+: using declaration, disposed at the end of the enclosing blockusing var reader = new StreamReader("members.csv");string? header = reader.ReadLine();

A using statement is shorthand for try { … } finally { obj?.Dispose(); }. If a type implements IDisposable, use it inside using unless something else owns it.

Implementing IDisposable

RenderBuffer.cs
public sealed class RenderBuffer : IDisposable{    private IntPtr _gpuHandle;          // a native resource    private readonly FileStream _log;   // a managed disposable we own    private bool _disposed;     public RenderBuffer(string logPath)    {        _gpuHandle = NativeGpu.Allocate(1024 * 1024);        _log = File.OpenWrite(logPath);    }     public void Draw()    {        ObjectDisposedException.ThrowIf(_disposed, this);   // .NET 7+        // … use the buffer …    }     public void Dispose()    {        if (_disposed) return;          // safe to call twice        NativeGpu.Free(_gpuHandle);        _gpuHandle = IntPtr.Zero;        _log.Dispose();                 // dispose what you own        _disposed = true;    }}
  • Dispose everything your object owns that is disposable.
  • Make Dispose safe to call more than once.
  • After disposal, throw ObjectDisposedException if someone uses the object.
  • For non-sealed classes with native resources, look up the full “dispose pattern” with protected virtual void Dispose(bool disposing) and a finalizer, or better, wrap the handle in a SafeHandle.

IAsyncDisposable

AsyncUsing.cs
await using var stream = new FileStream("big.bin", FileMode.Create);await stream.WriteAsync(data);
Quick check

What does the garbage collector NOT manage for you?

Quick check

A using statement is equivalent to…

Practice

Create a class Timer3D : IDisposable that starts a Stopwatch in its constructor and, in Dispose, prints “<name> took X ms”. Use it with using around a loop that sums 1 to 10 million, so the time is printed automatically at the end of the block.

Show the solution
Solution.cs
using System.Diagnostics; using (new Timer3D("Sum loop")){    long sum = 0;    for (int i = 1; i <= 10_000_000; i++) sum += i;    Console.WriteLine(sum);} public sealed class Timer3D : IDisposable{    private readonly string _name;    private readonly Stopwatch _sw = Stopwatch.StartNew();    public Timer3D(string name) => _name = name;    public void Dispose() => Console.WriteLine($"{_name} took {_sw.ElapsedMilliseconds} ms");}
Output
50000005000000
Sum loop took 9 ms

Remember

  • IDisposable.Dispose() releases non-memory resources immediately.
  • Always wrap disposable objects you create in using.
  • using = try/finally with Dispose; it runs even on exceptions.
  • Implement IDisposable when your class owns disposable or native resources.
0 of 60 lessons completed