C#,WPF,异步GUI更新和内存泄漏

时间:2014-07-10 09:01:28

标签: c# wpf

private delegate void UpdateTextBoxDelegate(System.Windows.DependencyProperty dp, Object     value);
..
UpdateTextBoxDelegate updateTextDelegate = new UpdateTextBoxDelegate(textBox1.SetValue);
..
foreach(..)
    Dispatcher.Invoke(updateTextDelegate, System.Windows.Threading.DispatcherPriority.Background, new object[] { TextBox.TextProperty, content.ToString() });

这个东西泄漏了。随着任务的到来,我正在使用一些进度信息更新GUI,它工作正常,但最后一行中的content.ToString()泄漏。我只能推测通过Dispatcher会保留对该字符串的引用,直到它被销毁(当我关闭保存它的对话框时,内存将被释放)。 非常明显的是,只是通过观察内存使用模式来吞噬内存的字符串(开始缓慢,然后随着字符串变大而向下倾斜10meg),我还完成了挂起的进程的转储(内存不足)并使用windbg调试..一些跟踪将它放到许多char []和gui框架文本框等) 当我使用显式SetValue时,即使是异步,为什么旧​​内容不符合垃圾回收的条件?

建议? : - )

1 个答案:

答案 0 :(得分:0)

首先,如果您已经发布了引用,则不必担心内存,请将剩余部分留给垃圾收集器来完成它的工作。

其次,您可以做的是通过限制更高代的对象来使GC的工作变得更容易。如果在第一次扫描中可以清洁物体,则GC更喜欢。

更多关于Fundamentals of Garbage Collection: Generations

不被垃圾收集器收集的问题是对象的生成

gen 0在未被引用后的第一次扫描中被清除

但如果在垃圾收集扫描内存时仍然引用,则同样会被提升为gen1

和第2代等等

因此,为了尽量减少促销,您可以将值复制到本地变量

例如

foreach(..)
{
    string value = content.ToString();
    Dispatcher.Invoke(updateTextDelegate, DispatcherPriority.Background, new object[] { TextBox.TextProperty,  value });
}