最近,我通过在单独的线程(STA)中使用控件创建和填充数据来进行性能优化。之后我在应用程序中发现内存泄漏:从DataGridView
继承的网格没有被释放,从而保留了大量内存:
经过一番调查后,我发现原因是订阅SystemEvents.UserPreferenceChanged
事件:
因此,目标是摆脱此订阅以释放对象。 我花时间测试通过谷歌搜索发现的一些方法(例如这一个:Memory Leak in ToolStripTextBoxControl),但没有成功。
答案 0 :(得分:-1)
这是我的解决方案。它并不完美,但解决了这个问题:
我发现事件SystemEvents.UserPreferenceChanged
的订阅/取消订阅位于方法OnHandleCreated/OnHandleDestroyed
(类DataGridView
)中。
public class MyDataGridView : DataGridView
{
...
#region Memory leak fix
int _eventSubscriptionCount;
/// <summary>
/// Hack to fix event handler leak
/// </summary>
private void MemoryLeakFix()
{
Disposed += OnDisposed;
}
/// <summary>
/// In some cases subscription keeps PinkDataGridView (and containing it controls) from removing by GC
/// </summary>
private void OnDisposed(object sender, EventArgs eventArgs)
{
for (int i = 0; i < _eventSubscriptionCount; i++)
{
base.OnHandleDestroyed(new EventArgs()); // unsubscribe SystemEvents.UserPreferenceChanged
}
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
Interlocked.Increment(ref _eventSubscriptionCount);
}
protected override void OnHandleDestroyed(EventArgs e)
{
base.OnHandleDestroyed(e);
Interlocked.Decrement(ref _eventSubscriptionCount);
}
#endregion Memory leak fix
}