C# DISCUSSION

When do I need IDisposable and using in C#, and do I also need a finalizer?

Started by jackcroger IDisposableusing statementfinalizerunmanaged resourcesSerialPort
4 replies 248 views 5 participants
Latest activity · 30 Sep 2026

When do I need IDisposable and using in C#, and do I also need a finalizer?

jackcroger C# Forum
#1

My logging tool opens a SerialPort and a FileStream. After closing the form and reopening it, I get an access denied error for COM3, or a message that the file is being used by another process, until I restart the application. I thought the garbage collector cleans up objects that are no longer referenced.

What is IDisposable for when the runtime already has a garbage collector, when should my own classes implement it, and is the full pattern with Dispose(bool) and a finalizer always required?

Community replies 4

Re: When do I need IDisposable and using in C#, and do I also need a finalizer?

#2

The garbage collector manages memory only, and it runs when it decides memory is needed, which may be seconds later or not before the program exits. It knows nothing about the operating system handle behind a COM port or an open file. Those are released when Dispose() or Close() is called or, as a last resort, when the object's finalizer eventually runs at some unpredictable time after a collection.

Your old SerialPort object is unreachable but not yet finalized, so COM3 is still open when the new form tries to open it. IDisposable is the contract for deterministic clean-up: call Dispose when you are done instead of waiting for the collector.

Re: When do I need IDisposable and using in C#, and do I also need a finalizer?

#3

For objects used within one method, use using: using (var fs = new FileStream(path, FileMode.Append)) { ... }, or the declaration form from C# 8, using var fs = new FileStream(path, FileMode.Append);, which disposes at the end of the enclosing scope. Both compile to try/finally, so Dispose runs even when an exception is thrown.

Objects that live as long as a form, like your serial port, must be disposed by their owner. A class with an IDisposable field should implement IDisposable itself and dispose its fields in its own Dispose. In WinForms, do it in the form's Dispose(bool) override or in the FormClosed handler, and unsubscribe from DataReceived before disposing the port.

Re: When do I need IDisposable and using in C#, and do I also need a finalizer?

#4

The full pattern with a finalizer is only needed when your class directly owns an unmanaged resource, such as a raw IntPtr handle from P/Invoke. Then you write public void Dispose() { Dispose(true); GC.SuppressFinalize(this); }, a protected virtual void Dispose(bool disposing) that releases managed fields only when disposing is true and unmanaged ones always, and a finalizer that calls Dispose(false). On the finalizer path other managed objects must not be touched, because they may already have been finalized.

If the class only wraps managed disposables such as streams, ports and timers, do not write a finalizer; a simple Dispose that calls theirs is enough. Even for raw handles, wrapping the handle in a SafeHandle is preferred over writing a finalizer yourself.

Re: When do I need IDisposable and using in C#, and do I also need a finalizer?

#5

Some practical rules. Dispose must be safe to call twice, so keep a bool _disposed flag and return early. After disposal, public methods should throw ObjectDisposedException. Do not dispose objects you do not own, for example a stream passed in by the caller; note that StreamReader disposes its underlying stream unless constructed with leaveOpen: true. For clean-up that has to await, there is IAsyncDisposable with await using.

The code analysis rules CA2000 and CA1001 find most missing Dispose calls at build time. One point specific to serial ports: the documentation advises waiting a moment after Close() before calling Open() again, because the port may not be released instantly.

TEP COMMUNITY