1

This issue has been perplexing me for quite a while. I'm trying to dispose of a connection to a database, but it keeps leaking no matter how I try to dispose of it. Worse yet, it's supposed to dispose automatically.

Long story short, I have a HostedService that starts with the following code:

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        using (var scope = _serviceProvider.CreateScope())
        {
            _logger.LogDebug($"Инициализация операторов");
            using (var operatorRepo = scope.ServiceProvider.GetService<IOperatorRepository>()) {
                var availableOperators = operatorRepo.GetAllOperatorsWithSkills();
                _logger.LogDebug($"Инициализовано {availableOperators.Count()} операторов");

                foreach (OperatorRow opRow in availableOperators)
                {
                    OperatorMeta opMeta = new(opRow.Idr, opRow.Name, opRow.Number, opRow.OperatorSkills.Select(skill => (skill.SkillId, skill.Experience)));
                    if (!TryAddOperator(opMeta))
                        throw new ArgumentException($"Оператор с id {opRow.Idr} уже был добавлен!");
                }
                if (Convert.ToBoolean(_configuration.GetSection("isOperatorTesting")?.Value))
                {
                    _globalOperatorPool.TryAdd(
                        -1,
                        new CampaignOperator(
                            new OperatorMeta(-1, "Test operator", _configuration.GetSection("testOperatorNumber").Value, Enumerable.Empty<(int, int)>()),
                            OperatorState.Unassigned)
                        );
                }
            }
        }
    }

I have tried to wrap the insides of the using in a try finally blocks just in case but I honestly don't see how that would be an issue because the using isn't inside of one. Still, connection doesn't close.

The underlying class of IOperatorRepository extends from a chain of two classes which extend from LinqToDB.DataConnection. It's the only IDisposable in the chain.

Honestly, I'm stumped. Any help would be appreciated.

Edit: I feel like I should specify that the connection class does indeed return ObjectDisposedException, but the connection stays open in the database, and more are made constantly as if they're not being reused.

Johnny Cache
  • 1,033
  • 7
  • 12
  • `using` blocks is enough to dispose the connection. However, it's by ADO.NET design, that the pooled connections will return to the pool after closing the connection object, and it will be destroyed (removed from the pool) when one of the pooler conditions is met (e.g. inactivity, invalid, or connection has been served). – iSR5 Jun 30 '22 at 10:58
  • 1
    you can also use `ClearAllPools` https://learn.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlconnection.clearallpools?view=dotnet-plat-ext-6.0 – iSR5 Jun 30 '22 at 11:00
  • @iSR5 If the connections are returned to the pool on dispose, then what the hell does DataConnection.Close() do? – Johnny Cache Jun 30 '22 at 11:46
  • `DataConnection.Close()` would release the connection so it can be reused again, and it would be destroyed if the connection either been inactive for certain amount of time or it's invalid or it's marked as served, which is determined by the pooler. – iSR5 Jun 30 '22 at 11:51
  • 2
    here is a good reference : https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/sql-server-connection-pooling – iSR5 Jun 30 '22 at 11:52

0 Answers0