У меня есть утечка памяти в моем приложении, настоящий источник которой я не могу найти. В элементе управления с именем DataTableEditor
есть эта строка кода:
refreshButton.DataBindings.Add("Enabled", asyncSqlResultsViewer, "CanRefresh", true, DataSourceUpdateMode.Never);
asyncSqlResultsVewer
— это просто пользовательский элемент управления с DataGridView
, который показывает данные. Используется для асинхронной загрузки данных, но это больше не так. Элемент управления DataTableEditor
— это еще один пользовательский элемент управления, содержащий элемент AsyncSqlResultsVewer
. Утечка кажется связанной с этим, потому что она показывает PropertyDescriptor
как часть пути, который удерживает объект в живых:
Я новичок в использовании .NET Memory Profiler, но дело в том, что удаление строки выше устраняет утечку. Удаление привязки с помощью DataBindings.Remove
также устраняет утечку. Но должно ли это случиться? asyncSqlResultsVewer
удалены и, насколько я знаю, разыменованы вместе с DataTableEditor
, поэтому каждая ссылка среди них не должна поддерживать их жизнь, пока никто другой не ссылается ни на один из них (правильно?). Я все еще могу удалить привязку на всякий случай или в качестве хака, но я хотел бы, чтобы кто-нибудь помог мне понять, какова настоящая причина утечки.
Если вы сомневаетесь, что это настоящая утечка памяти, приложение вылетает после открытия и закрытия нескольких DataTableEditor
, которые показывают большой объем данных. Кроме того, профилировщик сообщает мне, что объект был удален, но ссылки на него все еще есть.
Если есть какая-либо другая информация, которая может помочь мне разобраться в этом, пожалуйста, дайте мне знать.
Редактировать: кажется, я знаю, откуда может произойти утечка. refreshButton
выше является экземпляром этого класса:
public class ToolStripBindableButton : ToolStripButton, IBindableComponent, INotifyPropertyChanged
{
private ControlBindingsCollection dataBindings;
private BindingContext bindingContext;
public ControlBindingsCollection DataBindings
{
get
{
if (dataBindings == null) dataBindings = new ControlBindingsCollection(this);
return dataBindings;
}
}
public BindingContext BindingContext
{
get
{
if (bindingContext == null) bindingContext = new BindingContext();
return bindingContext;
}
set { bindingContext = value; }
}
public override Image Image
{
get { return base.Image; }
set { SetImage(value); }
}
private void SetImage(Image value)
{
if (base.Image != value)
{
base.Image = value;
OnPropertyChanged(new PropertyChangedEventArgs("Image"));
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null) PropertyChanged(this, e);
}
}
Добавление переопределения Dispose
и выполнение dataBindings.Clear()
устраняет утечку. Это то, что я должен сделать, или настоящая причина утечки находится где-то еще?