【问题标题】:OnUserPreferenceChanged hang: DataGridView created in separate threadOnUserPreferenceChanged 挂起:DataGridView 在单独的线程中创建
【发布时间】:2016-02-02 03:39:54
【问题描述】:

最近我通过使用在单独线程 (STA) 中创建和填充数据的控件进行了性能优化。之后我在应用程序中发现了内存泄漏:从DataGridView 继承的网格没有被释放以保持大量内存:

经过一番调查,我发现原因是订阅了SystemEvents.UserPreferenceChanged事件:

所以目标是摆脱这个订阅来释放对象。 我花时间测试了一些通过谷歌搜索找到的方法(例如这个:Memory Leak in ToolStripTextBoxControl),但没有成功。

【问题讨论】:

  • 为什么是“-1”?这个问题有什么问题?

标签: c# multithreading winforms datagridview memory-leaks


【解决方案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
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    相关资源
    最近更新 更多