アプリケーションにメモリリークがあり、実際のソースを見つけることができません。このコード行は、次のようなコントロールにありますDataTableEditor
。
refreshButton.DataBindings.Add("Enabled", asyncSqlResultsViewer, "CanRefresh", true, DataSourceUpdateMode.Never);
は、データを表示asyncSqlResultsVewer
するだけのユーザーコントロールDataGridView
です。データを非同期でロードするために使用されましたが、現在はロードされていません。コントロールは、DataTableEditor
を含む別のユーザーコントロールですAsyncSqlResultsVewer
。リークはPropertyDescriptor
、オブジェクトを存続させているパスの一部として表示されるため、これに関連しているようです。
私は.NETMemoryProfilerを使用している初心者ですが、上の行を削除するとリークがなくなります。との境界を削除すると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()
、リークが修正されます。これは私がすることになっていることですか、それともリークの本当の原因はまだ他の場所にありますか?