C# SQLite数据库连接类出现ObjectDisposedException问题求助
System.ObjectDisposedException in Your Custom SQLite DBConnection Class Hey there! Let's break down why you're seeing that frustrating System.ObjectDisposedException when your DBConnection instance goes out of scope, and how to fix it for good.
What's Causing the Exception?
This error almost always happens because you're trying to interact with a SQLiteConnection object that's already been disposed of. If your current DBConnection class uses a finalizer (destructor) that tries to close or dispose the connection, but the connection was already explicitly disposed earlier (either by you calling Dispose() manually, or via a using statement), the finalizer will attempt to access an already dead object—hence the exception.
The Correct Approach: Implement IDisposable Properly
Database connections are considered "unmanaged-wrapped" resources, so you need to follow C#'s standard IDisposable pattern to handle cleanup safely. Here's how to rewrite your DBConnection class to avoid this issue:
using System; using System.Data.SQLite; public class DBConnection : IDisposable { private SQLiteConnection _dbConnection; private bool _isDisposed = false; // Tracks if resources are already released public DBConnection(string connectionString) { _dbConnection = new SQLiteConnection(connectionString); _dbConnection.Open(); } // Public Dispose method for manual cleanup (or auto via `using`) public void Dispose() { Dispose(true); GC.SuppressFinalize(this); // Tell GC not to run the finalizer—we already cleaned up } // Protected Dispose method that handles both manual and GC-triggered cleanup protected virtual void Dispose(bool disposing) { if (_isDisposed) return; // Exit if we've already cleaned up if (disposing) { // Clean up managed resources (like SQLiteConnection) only when manually disposing if (_dbConnection != null) { if (_dbConnection.State != System.Data.ConnectionState.Closed) { _dbConnection.Close(); } _dbConnection.Dispose(); _dbConnection = null; } } // If you had raw unmanaged resources (like Win32 handles), clean them up here _isDisposed = true; } // Finalizer (destructor) – only runs if Dispose() was never called manually ~DBConnection() { Dispose(false); } // Add your database operation methods here (e.g., ExecuteQuery, InsertData) }
Key Details to Note:
_isDisposedFlag: Prevents repeated cleanup attempts—this is the main fix for your exception. If the connection was already disposed, we skip trying to access it again.Dispose(bool disposing):- When
disposing = true: This means the method was called manually (or viausing), so we can safely clean up managed resources likeSQLiteConnection(since they're still alive). - When
disposing = false: This is the finalizer running, so we only touch unmanaged resources (if any)—managed resources might already be garbage collected, so we don't interact with them here.
- When
GC.SuppressFinalize(this): Once you manually dispose the object, the garbage collector doesn't need to run the finalizer, which improves performance and avoids redundant work.
How to Use Your Class Safely
Always wrap your DBConnection instances in a using statement—it automatically calls Dispose() when the block ends, ensuring proper cleanup and reducing the chance of the finalizer ever needing to run:
using (var db = new DBConnection("Data Source=your_database.db;Version=3;")) { // Perform your database operations here }
This should eliminate the ObjectDisposedException entirely, as you'll never have the finalizer trying to access a connection that's already been disposed.
内容的提问来源于stack exchange,提问作者Derek Mandl

