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
相关产品推荐
相关产品推荐

