Nano Hash - криптовалюты, майнинг, программирование

LINQ to SQL, переопределить удаление

Я создаю LINQ to SQL DataContext, передавая ему уже открытое соединение. Это работает, за исключением того, что теперь у меня везде утечка соединений, потому что, хотя я удаляю DataContext, когда я закончу, соединение никогда не закрывается. Я так понимаю, это сделано намеренно.

Что я хотел бы сделать, так это убедиться, что мое соединение закрывается после удаления моего DataContext.

Я попытался переопределить Dispose в DataContext, например:

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

Однако это не работает ... Я получаю исключение ObjectDisposedException. Установка точки останова показывает мне, что к этому моменту все уже удалено!

Единственный обходной путь, который я нашел, - это скрыть метод Dispose в DataContext. Нравится:

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

        base.Dispose();
    }

Однако для меня это немного неприятный запах кода. Каков рекомендуемый способ действовать здесь?

Полный пример кода (DataClasses1DataContext - пустой 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();
    }
}

  • В чем заключается исключение при переопределении вызова метода Dispose? 16.02.2012
  • Я получаю исключение ObjectDisposedException 16.02.2012
  • Что означает исключение ObjectDisposedException? 16.02.2012
  • Необработанное исключение типа «System.ObjectDisposedException» произошло в System.Data.Linq.dll. Дополнительная информация: Невозможно получить доступ к удаленному объекту. 16.02.2012
  • К моменту, когда я скрывал переопределение Dispose (bool Disposing), объект соединения, как и все свойства контекста, уже были удалены. Поскольку сначала вызывается метод Dispose () ... 16.02.2012

Ответы:


1

Проблема в том, что Dispose() устанавливает disposed перед вызовом Dispose(bool). Это вызывает исключение при вызове Connection. Кажется, нет никакого способа обойти это.

Однако я должен спросить, зачем это нужно? Dispose(bool) вызывает Dispose на Provider, который содержит Connection и должен обработать его автоматическое закрытие.

16.02.2012
  • Спасибо. Глядя на отражатель, кажется, что соединение удаляется только при определенных условиях (возможно, если оно было открыто с помощью Linq to SQL). 16.02.2012
  • И, по крайней мере, на первый взгляд кажется, что Linq to SQL не имеет модели общедоступного поставщика, которую я могу просто изменить. Похоже, мой обходной путь - единственный способ. 16.02.2012
  • @TheNextman: Вы используете SqlProvider? Похоже, он всегда должен закрывать соединение. Если я не пропущу где-то, где conManager устанавливается на null (он создается вне ветки). 16.02.2012
  • Мне это непонятно после прочтения кода в Reflector. Однако документация (и подкрепленная запуском моего примера кода при использовании SQLServer: General Statistics: User Connections performance counter) демонстрирует, что если вы либо дадите Linq to SQL уже открытое соединение, либо сами откроете его объект соединения, оно будет < i> не уничтожать / закрывать его в уничтожении 16.02.2012
  • @TheNextman: Интересно, жаль, что нет простого способа добраться до объекта подключения во время Dispose(). Или, если на то пошло, способ явно запросить управление, например, как обрабатывается Stream. 16.02.2012
  • После еще одного исследования: L2S удалит соединение, если вы создадите DataContext с помощью строки подключения. Если вы создаете соединение, оно не будет удалено. Имеет смысл :) 17.02.2012
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..