Eliminate Database Connection Leaks in VB.NET with the Using Statement
Resource leaks in VB.NET arise when Dispose calls are missed on database connections and file streams. The Using statement guarantees deterministic cleanup, even on exceptions. This post shows a clear example, discusses trade‑offs, and offers actionable steps to adopt Using in your projects.
06 Sept 2025, 00:59 UTC

Problem: Resource Leaks in Database Access
In many VB.NET applications, developers open SqlConnection, FileStream, or other unmanaged handles and forget to close them. When a connection pool is exhausted or file handles accumulate, the application can crash or refuse new requests. The root cause is that the code path that opens the resource often does not guarantee a corresponding Close or Dispose call, especially when exceptions bubble up.
Thesis: The Using Statement Guarantees Deterministic Disposal
The Using construct in VB.NET is a language feature that automatically calls Dispose on any object that implements IDisposable when the block ends, even if an exception is thrown. This eliminates the need for manual Try…Finally patterns and ensures resources are released promptly.
Concrete Example: Opening a SQL Connection Safely
Below is a minimal console‑app snippet that opens a connection, executes a query, and guarantees that the connection is closed immediately after the Using block finishes.
Imports System.Data.SqlClient
Module Program
Sub Main()
Dim connString As String = "Server=myServer;Database=myDb;User Id=myUser;Password=myPass;"
Using conn As New SqlConnection(connString)
conn.Open()
Dim cmd As New SqlCommand("SELECT COUNT(*) FROM Users", conn)
Dim count As Integer = Convert.ToInt32(cmd.ExecuteScalar())
Console.WriteLine($"User count: {count}")
End Using ' conn.Dispose() is called here
Console.WriteLine("Connection closed. State: " & conn.State) ' Closed
End Sub
End Module
Key points:
- The
Usingblock createsconnand opens it. - When the code reaches
End Using, the runtime automatically callsconn.Dispose(). - Even if
ExecuteScalarthrows,Disposewill still run.
Nested Using: Cleanly Scoping Multiple Resources
When you need more than one disposable object, nest Using blocks. The inner block is disposed before the outer block, preserving the natural order of resource release.
Using conn As New SqlConnection(connString)
conn.Open()
Using cmd As New SqlCommand("INSERT INTO Logs(msg) VALUES(@msg)", conn)
cmd.Parameters.AddWithValue("@msg", "Test")
cmd.ExecuteNonQuery()
End Using ' cmd.Dispose()
End Using ' conn.Dispose()
Trade‑Offs and Limitations
- Only IDisposable Types: The compiler rejects non‑IDisposable objects. If a class claims to implement
IDisposablebut doesn’t release unmanaged resources inDispose,Usingwill not help. - Legacy VB: This feature is not available in VB6 or VBScript; it requires VB.NET targeting the .NET runtime.
- Exception Safety: While
UsingensuresDisposeruns, it does not catch or handle exceptions. Combine it withTry…Catchif you need error handling.
Actionable Guidance
- Adopt Using Early: Replace all manual
Try…Finallypatterns withUsingfor disposable resources. - Verify Dispose Implementations: If you write a custom class that implements
IDisposable, ensure it releases all unmanaged handles in theDisposemethod. - Test Resource Count: In unit tests, instrument the connection count or use a tool like Process Explorer to verify that handles drop to zero after the block.
- Document Usage: Add a comment or XML doc that the block guarantees disposal, helping future maintainers understand why
Usingis used.
By making Using a standard part of your coding style, you eliminate a common source of bugs—resource leaks—and make your VB.NET applications more robust and easier to maintain.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.