You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RadListBox因ScrollView(ScrollInfo)Action引发内存泄漏问题

问题分析与解决方案

问题核心

使用RadListBox实时添加程序运行状态项时,仅在添加SelectedItem更新逻辑后出现内存泄漏:诊断工具显示WPF的ScrollInfo类型与Action对象堆积;该问题仅在Tab切换后可见的RadListBox中触发,不更新选中项或改用WinForms ListBox则无此问题,且与任务处理速度无关。

可能原因

  • RadListBox在控件不可见时,更新SelectedItem会触发内部ScrollInfo相关的订阅/引用未被正确释放,形成内存滞留。
  • 每次跨线程调用时创建新的委托实例,未被GC及时回收,堆积为Action对象。
  • 直接赋值SelectedItem会触发更复杂的内部绑定/视图更新逻辑,相比SelectedIndex更容易产生未释放的引用。

解决方案

1. 仅在控件可见时更新选中项

既然问题仅在Tab切换可见的ListBox中出现,可先判断控件可见性,避免在不可见时执行选中逻辑:

delegate void DInsertList(RadListBox nlistbox, string str);
public static void InsertList(RadListBox nlistbox, string str)
{
    if (nlistbox.Dispatcher.Thread == Thread.CurrentThread)
    {
        if (str != null)
        {
            if (nlistbox.Items.Count > 100)
            {
                nlistbox.Items.RemoveAt(0);
            }
            
            nlistbox.Items.Add(str);
            
            // 仅当控件可见时更新选中项
            if (nlistbox.IsVisible)
            {
                // 改用SelectedIndex替代SelectedItem,减少内部引用开销
                nlistbox.SelectedIndex = nlistbox.Items.Count - 1;
            }
        }
    }
    else
    {
        // 复用委托实例,避免每次创建新对象
        DInsertList call = InsertList;
        nlistbox.Dispatcher.BeginInvoke(call, nlistbox, str);
    }
}

2. 优化跨线程委托调用

避免每次创建新的委托实例,直接复用方法引用,减少Action对象的堆积。

3. 优先使用SelectedIndex替代SelectedItem

SelectedIndex仅传递索引值,内部逻辑更轻量,相比直接赋值SelectedItem(会触发项的引用绑定),更不容易产生未释放的内存引用。

4. 检查Telerik控件版本

若上述方法无效,可能是RadListBox的已知内存泄漏bug,尝试升级到最新的Telerik UI for WPF版本,官方可能已修复此类问题。

内容的提问来源于stack exchange,提问作者user23761619

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 05:42:49