Утечки памяти после закрытия winform с настраиваемой таблицей

У меня есть диалоговое окно C # WinForm, которое содержит настраиваемый элемент управления таблицей со строками и ячейками, которые также являются настраиваемыми элементами управления. После закрытия (не скрытия) этого диалога у меня возникает утечка памяти (и это подтверждается профилировщиком памяти .NET).

Из информации, которую я получаю от профилировщика, я думаю, что он связан с удалением этих элементов управления, но я не уверен, как это исправить.

В элементе управления таблицей у меня есть список строк:

private readonly List<CustomRow> _rows = new List<CustomRow>(); 

В каждой строке у меня есть список ячеек:

List<CustomCell> _cells = new List<CustomCell>();

К настоящему времени удаление элементов управления было выполнено автоматически сгенерированным кодом в Designer.cs:

protected override void Dispose(bool disposing)
{
    if (disposing && (components != null))
    {
         components.Dispose();
    }
    base.Dispose(disposing);
}

Но теперь я думаю, нужно ли мне перенести код утилизации в файл .cs и добавить что-то подобное, например, для таблицы:

protected override void Dispose(bool disposing)
{
     if (disposing)
     {
          if (components != null)
          {
              components.Dispose();
          }
          // dispose each row here                
     }
     base.Dispose(disposing);
}

Или это происходит автоматически и причина утечки памяти другая? (Что это может быть?)


person demonplus    schedule 26.12.2015    source источник
comment
Просто чтобы убедиться, что вы используете Show, а не ShowDialog, когда показываете свой - хм, диалог? А метод Dispose называется?   -  person Ivan Stoev    schedule 26.12.2015
comment
@IvanStoev Я использую Show (), а не ShowDialog (). Еще одна важная вещь заключается в том, что эти диалоги не отображаются напрямую, а добавляются как элементы управления в форму с вкладками (по одному на вкладку), а затем для основной формы вызывается Show ().   -  person demonplus    schedule 26.12.2015


Ответы (1)


Образец Dispose отличается от того, что вы думаете. Dispose не предотвращает утечки памяти.

Шаблон удаления используется для предотвращения утечек неуправляемой памяти с помощью неуправляемого кода. Это означает, что если вы используете неуправляемый код / ​​библиотеки, вы должны вызвать деинициализацию (неуправляемого кода) в методе Dispose.


Проблема, с которой вы столкнулись, заключается в том, что у вас есть набор данных, который живет дольше, чем ваша форма. Это означает, что когда элемент управления регистрирует события в строке данных / таблице (например, события RowChanged), форма сохраняется активной элементом управления данными, на который имеется ссылка (из-за обработчик событий) набором данных. Помните, что обработчики событий являются надежными ссылками и могут вызвать утечку памяти, подобную вашей.

Я не знаю, какие компоненты вы используете, но вы, вероятно, могли бы легко исправить это.

Например: когда форма закрывается / закрывается, просто сбросьте GridView1.DataSource = Null. Это заставит компонент отменить регистрацию изменений / измененных событий DataTable

так, как вы "привязываете" данные к компонентам, просто "отвяжите" их таким же образом и снова профилируйте

person Jeroen van Langen    schedule 26.12.2015
comment
Спасибо, я думаю, вы правы. Компоненты написаны нами самими. Привязка данных не используется, для добавления данных используется только метод addRow (). Я могу все очистить методом clearAll (). Как вы думаете, я должен попытаться вызвать это, когда форма будет удалена? - person demonplus; 26.12.2015
comment
Вам следует проверить, регистрируете ли вы события на DataTable/DataSet. В таком случае отмените регистрацию на странице «Утилизация / закрытие». - person Jeroen van Langen; 26.12.2015