2011-09-01 56 views
4

在矿山的应用程序我有一个性能问题的一个WPF内存泄漏我解决不了:与衍生文本框

这个应用程序是建立与来自TextBox -class导出输入控件,有自己的ControlTemplate Themes\Generic.xaml

我的问题是,这些控件不会被释放后,他们不再使用。如果我使用SciTech MemoryProfiler来查看它们,我会发现它们由System.Windows.Documents.TextEditor的实例持有,并且TextEditor-实例通过终结器队列持有。
内存分析器将一个警告附加到TextEditor - 例程中,称“实例间接根据终结器队列”。
有没有人知道这里发生了什么?不允许直接从TextBox派生?还是我忘记了一些重要的实施?

为实现附加信息:
的一些派生的控件的实现是很简单的。在类构造函数中,DefaultStyleKeyProperty的元数据被覆盖,并且没有事件处理程序附加到控件模板中包含的元素。喜欢的东西:

public class MyDerivedTextBox : TextBox{ 

    static MyDerivedTextBox(){ 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(MyDerivedTextBox), new FrameworkPropertyMetadata(typeof(MyDerivedTextBox))); 
    } 

} 

(简化)风格看起来是这样的:

<Style TargetType="{x:Type myApp_controls:MyDerivedTextBox}"> 
    <Setter Property="SnapsToDevicePixels" Value="True"/> 
    <Setter Property="UndoLimit" Value="1"/> 
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>   
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type myApp_controls:MyDerivedTextBox }"> 
       <Border Name="Border" ... > 
        <ScrollViewer Margin="1" x:Name="PART_ContentHost" /> 
       </Border> 
      </Setter.Value> 
     </Setter> 
</Style> 

回答

3

终结队列
约终结队列中的问题的答案,所看到的效应不是一个常数之一:定稿是根本就没有在我分析了记忆点结束。这里的问题是了解我使用的工具(和环境)。然而

内存泄漏
泄漏itselfs是一个实际问题,事实证明,它被the same thing我还观察到在其它位置(在相同的应用程序)。 对CLR属性的绑定未实现INotifyPropertyChangedhttp://support.microsoft.com/kb/938416/en-us

这是我的第一个WPF项目,同时它发展到一个巨大的应用程序。在我开始的时候,我并没有意识到,WPF在上述绑定方面存在问题,并且在开发过程中,我尝试尽可能多地使用数据绑定,但不关心目标对象。现在应用程序变得如此之大,客户端数量急剧增加之后,这些内存问题就被揭示出来(并导致了非常奇怪的效果)。

解决了最有问题的绑定后,终止器队列的效果也大大降低。看起来之前,内存泄漏导致了对象终止的延期执行(这只是一个假设,我没有深入研究GC行为)。

导出文本框:
我创建了一个小样本项目,这种派生的文本框控件,在内存分析器内的一些stresstests使用它们。就我对测试项目的观察而言,我可以从TextBoxes派生出来,因为我做得非常好。

Fazit
我只能强调应用程序创建过程中检查绑定的目标对象的重要性。否则,在应用程序中识别泄漏点将是很多工作。我希望这个解释能帮助别人不像我一样犯同样的错误。

1

不知道是否会改变什么,但不是在你的控制静态构造函数,你有没有尝试过这样的:

public MyDerivedTextBox() 
{ 
    this.DefaultStyleKey = typeof(MyDerivedTextBox); 
} 

这就是我更熟悉的模式。也许MetaDataOverride正在做些不可思议的事情。

顺便说一句,我注意到一些Silverlight内存问题,就是平板电脑输入服务(参见http://www.wintellect.com/CS/blogs/sloscialo/archive/2011/04/13/silverlight-memory-leaks-and-automationpeers.aspx)带来了无法解释的AutomationPeers。

+0

+1谢谢你的回答。最后,这是我在另一个位置已经存在的问题:对象属性的DataBindings既未实现INotifiyPropertyChanged也未从DependencyObject派生。在我开始这个项目的时候,我并不知道在大型项目中这会有多糟糕。对于从TextBoxes派生,我现在可以肯定地说,这工作正常。 – HCL