Frage

I am creating a LINQ to SQL DataContext by passing it an already open connection. This works, except I'm now leaking connections everywhere because although I dispose the DataContext when I'm finished, the connection never gets closed. I understand this is by design.

What I would like to do is ensure that my connection gets closed once my DataContext is disposed.

I have tried to override Dispose on the DataContext, like this:

protected override void Dispose(bool disposing)
{
    this.Connection.Close();
}

However, this does not work... I get an ObjectDisposedException. Setting a breakpoint shows me that everything is already disposed at this point!

The only workaround I have found, is to hide the Dispose method on DataContext. Like this:

    public new void Dispose()
    {
        this.Connection.Close();

        base.Dispose();
    }

However, this has a bit of a bad code smell to me. What is the recommended way to proceed here?

Complete code sample (DataClasses1DataContext is an empty DataContext):

class Program
{
    static void Main(string[] args)
    {
        string connectionString = "server=localhost;initial catalog=master;Integrated Security=SSPI;";

        for (int i = 0; i < 100; i++)
        {
            var connection = new SqlConnection(connectionString);
            connection.Open();

            var ctx = new DataClasses1DataContext(connection);
            ctx.ExecuteCommand("declare @i int");

            ctx.Dispose();
        }

        Console.ReadKey();
    }
}

public partial class DataClasses1DataContext
{
    protected override void Dispose(bool disposing)
    {
        // This will throw an ObjectDisposedException
        // this.Connection.Close();
    }

    public new void Dispose()
    {
        // This will work
        // this.Connection.Close();

        //base.Dispose();
    }
}
War es hilfreich?

Lösung

The problem is Dispose() sets disposed before calling Dispose(bool). This causes the exception when you call Connection. There does not appear to be a way around this.

However I have to ask, why is this necessary? Dispose(bool) calls Dispose on the Provider which contains the Connection and should handle closing it automatically.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top