2011-09-01 37 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