You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# SQLite数据库连接类出现ObjectDisposedException问题求助

Fixing 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:

  • _isDisposed Flag: 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 via using), so we can safely clean up managed resources like SQLiteConnection (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.
  • 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:35:20