2011-04-26 74 views
23

我有一個WPF應用程序,它很慢。WPF:緩慢的模板實例

它是不是的渲染。首先,渲染非常簡單,其次,我用WPF性能工具包來查看 - 沒有任何東西。

這是不是在我自己的代碼。首先,單元測試工作速度很快,其次,如果我將所有DataTemplates替換爲空白,則一切工作都很快。

到目前爲止,它看起來像緩慢的部分是模板實例化。也就是說,當你啓動應用程序並打開一些複雜的屏幕時,需要很多的時間。並且「很多」我的意思是「很多」。有時可能需要3-5秒 - 例如,當存在一個包含100行的數據網格時。但是,當你轉到另一個選項卡,然後返回到同一個屏幕時,它會快速打開(只要它的視圖模型保持放置狀態)。

這很煩人,不僅因爲它很慢,而且因爲我對此無能爲力。如果我有過一些緩慢控制,我可以,也許,顯示一些「開放,請稍候」消息或東西...

此外,當我看一些其他的WPF應用程序(最值得注意的是,ILSpy)儘管數據量很大,但他們似乎工作得相當快。這讓我相信我可能做錯了什麼。但我不知道從哪裏開始。

任何想法?任何經典錯誤?有小費嗎?

+0

你想知道和做出有教育的猜測是什麼問題。不要懷疑。不要猜測,也不要指望Performance Toolkit告訴你。 [這是如何找出。](http://stackoverflow.com/questions/375913/what-c​​an-i-use-to-profile-c-code-in-linux/378024#378024) – 2011-04-26 13:58:30

+0

@Mike:是,我廣泛使用這種原始採樣技術,並且在普遍性能下降時幫助我很多。但在這種情況下,我只是沒有足夠的時間來停止執行,因爲性能下降最多隻能持續3-5秒。另外,在我設法阻止它的極少數情況下,它總是停留在WPF的內核中。我也追求這個線索(在ILSpy的幫助下),但到目前爲止,它看起來很無望。因此,我的問題更多的是與WPF相關的問題。 – 2011-04-26 16:52:05

+0

對。它停在WPF的內核中,但是堆棧上有什麼?堆棧中的每一行都負責這段時間。我曾經有人說過「哦,每次我停止它,它都在一些迭代器中,那有什麼好處?」答案是*很棒*,現在只需查看堆棧,就會發現問題。如果你猜猜問題是什麼,那麼它會告訴你,如果你是對的,如果你錯了,它會告訴你什麼是正確的問題。 – 2011-04-26 20:51:27

回答

1

您是否將您的WPF應用程序作爲64位應用程序運行?

然後WPF slow to start on x64 in .NET Framework 4.0可能會有所幫助。

+0

看起來不錯,但沒有。首先,我實際上運行該應用程序作爲一個32位進程(我使用一些本地DLL不存在於64位)。其次,即使我確信所有相關的代碼已經被打亂,速度也一樣慢。下面是我如何知道這一點:我啓動應用程序,創建一個新項目(我有'項目'的這個概念),測試用戶界面,並看到它很慢。然後我再次創建一個新項目(不關閉應用程序!)。在這一點上,所有舊模型和視圖模型都被扔掉了,並且創建了新模型。然後我再次測試用戶界面 - 而且速度又很慢。 – 2011-05-01 18:36:47

5

我exerience來自於WPF思維導圖應用NovaMind

幾個月前,我們完全重寫我們的中間層來解決我們所經歷的性能問題的工作。簡而言之,創建我們的用戶控件似乎是減速的方式。不幸的是,我找不到一個好的方式來描述性能,因爲WPF性能套件和商業應用程序(如ANTS Profiler)都不會提供有關此部分WPF過程的任何詳細信息。 (當時我問了this question

我們採取了通過反覆試驗來手動測試我們的應用程序,並刪除了部分用戶控件,以查看究竟是什麼罪魁禍首。

最後,我們通過完全重寫我們的控件來解決性能問題。我們也大大減少了視覺樹的複雜性。在重寫之前,我們最常用的用戶控件之一,當用Snoop進行檢查時,由61種不同的東西組成,現在只有3種。只要有可能,我們只會根據需要在視覺樹中添加內容。 (正如您在XAML中所知道的,即使您將事物設置爲Collapsed,也需要先創建它們)。 最後,我們不得不編寫自己的富文本渲染控件,因爲RichtextBox的內置速度非常慢,RichtextBox的可視化樹相當複雜。

我不知道這是否適用於您的情況,但我會建議您調查您的用戶控件並查看它們是否複雜。也許你有可以修剪的東西。 低懸的水果將是很難看得見的部分,或者可以用懶惰的方式創建。您可以根據需要在代碼後面創建這些部分,而不是將它們放在XAML中。這應該會對你有所幫助。

否則虛擬化是你的朋友,如果可能的話。在我們的情況下,我們不能那麼做。在您的數據模板

+0

我剛剛驗證了可視化樹的大小。大約需要1秒鐘的屏幕總共包含850個視頻。你的經歷是否過度?什麼樹大小可以接受? – 2011-05-06 17:30:58

1

用戶控制,不完全是壞主意,但如果你渴望的性能,那麼你應該考慮改用更輕控制。例如,擁有一個UserControl只是託管一個TextBox是非常糟糕的想法,因爲UserControl由ContentControl組成,ContentControl主機ContentPresenter和ContentPresenter將託管TextBox,所以如果您注意到您的可視樹,它有三個新的UI元素層。減少可視樹一定會提高性能。

最有可能,我會建議創建自定義控件這可能是一個完全具有能與你想呈現的數據,你可以在generic.xaml自己的自定義模板幾個依賴屬性一個新的控制。其次,您可以簡單地從現有控件派生出一個控件,並在generic.xaml中重新定義其默認模板。

這種方法當然會更好,因爲您將減少可視化樹,從而減少視覺狀態管理器的工作。

更改主題或模板將變慢,然後更改託管內容的元素。讓元素在其自己的通用資源字典中具有默認模板。

1
  • 建議您升級所有的資源 據他們會去,最好到 的App.xaml
  • 檢查是否可以使用靜態資源 而不是動態的,靜態的 都快得多
  • 如果可能的話,儘量在你的虛擬機使用depedency 性能,特別是如果 你對他們有很多在一次或者 他們有很多的特性。這將使wpf不必做一堆反思。
+0

1)資源已全部在app.xaml中。 2)我從不使用DynamicResource。只有靜態。3)不能這樣做:首先,依賴項屬性需要線程關聯,其次,它們實際上比POCO屬性慢很多。有關詳細信息,請參閱此文章:http://www.markusegger.com/blog/development.aspx?messageid=3dfccfc5-1a30-4af1-a924-da22f3ff6057 – 2011-05-05 17:08:25

+0

oppinions在#3上有所不同,因爲數據綁定依賴屬性的速度更快。 http://msdn.microsoft.com/en-us/library/bb613546.aspx至於線程關聯。是的,這是真的,但你綁定到的控件無論如何都是線程的親和力,所以你仍然必須處理那個..哦,好吧,只是把它扔出去:) – aL3891 2011-05-05 18:46:39

+0

另一個例子,也見相關文章鏈接http:// blog .resique-du-net.com/index.php?post/2010/02/24/DependencyProperties-or-INotifyPropertyChanged – aL3891 2011-05-05 21:55:22

1

你提到你正在使用一個DataGrid有,比方說,100行。你的性能問題的一個可能的罪魁禍首是,你使用的任何數據網格都不是在做虛擬化,所以你的視覺樹是巨大的。

通常情況下,WPF屏幕中的啓動時間很長,指向一個很大的可視化樹。

我不知道,如果你正在使用每行一個DataTemplate,或結合列,或者說一些第三方的網絡 - 但可以說你有8列與控制。根據你的網格/驗證/等,這可能是一個20-60個項目每行的可視化樹。如果你有一個組合框,那麼下拉菜單中的每個項目也可以被創建。

爲了解決這個問題只需要看完信息,並採取措施,當您去:

  1. 使用虛擬化控制儘可能多的。這意味着使用內部列表控件一個virtualizingstackpanel,並確保您的第三方控件做的一樣好(很多股票的WPF控件現在做的默認)
  2. 不要過度使用用戶控件,複合控件等添加深度增加了時間和投入數據模板或其他重複區域中的額外視覺樹深度加起來很快。
  3. 如果一切都失敗,顯示簡單的屏幕,並通過代碼添加控件來提高感知性能
1

這聽起來很相似,我有一個問題。我在此發佈修復程序:WPF UI Automation issue。只是爲了搜索者的利益發布,因爲它需要很長時間才能解決。