2009-01-23 32 views
3

我們有一個使用/ CLR編譯的MFC 8應用程序,它包含大量的Windows窗體用戶控件,並且包含使用ElementHost的WPF用戶控件。由於我們的軟件架構,我們不能直接使用HwndHost。我們在這裏觀察到一個非常奇怪的行爲,我們無法理解:我是WPF引擎中發現錯誤的發現者嗎?

當應用程序啓動期間CPU負載非常高並且存在大量ElementHost實例時,整個屬性引擎完全停止工作。例如,通常可以正常工作的動畫現在不會更新綁定屬性的值,它們只會在啓動後停留在某個隨機值。當我設置一個不綁定任何屬性的值時,該值被正確存儲在依賴項屬性中(調用getter返回新值),但是可視化表示永遠不會反映這一點。我將背景設置爲紅色,但背景顏色不變。

我們在很多運行Windows XP SP2的不同機器上測試過它,它具有很高的可重複性。

這裏有趣的是,事實上有一種情況,其中綁定屬性實際上從動畫中拾取新值,並且視覺根據屬性值進行更新。當我調整ElementHost的大小或隱藏並重新顯示父本機控件時。只要我這樣做,綁定到一個動畫的屬性拾取一個新的值,並基於新的屬性值重新渲染視覺效果 - 但只有一次 - 如果我想看另一個更新,我必須調整ElementHost的大小。

你對這裏可能發生的事情有什麼解釋嗎?或者我可以如何解決這個問題以找出答案?我能做些什麼來調試呢?有沒有一種方法可以獲得更多關於WPF實際執行或WPF可能崩潰的信息?對我來說,它目前看起來像WPF本身的錯誤,因爲它只發生在啓動時的高CPU負載。

+0

您是否正在使用線程處理工作進程? – JFV 2009-01-23 20:36:26

+0

沒有任何與WPF相關的事情正在UI線程上發生。 (創建和應用動畫設置屬性等)在WPF中實際上,如果我試圖設置一個屬性的UI線程會導致異常的任何其他。 – bitbonk 2009-01-23 21:56:25

+0

如果您有任何綁定的對象,您還必須在UI線程上更改它們。雖然我懷疑這是問題所在。 – bh213 2009-01-27 15:14:56

回答

1

有你如何在啓動時加載你的數據沒有詳細...如果你還沒有做它,可以考慮使用Dispatcher.BeginInvoke(具有優先級低於渲染)或BackgroundWorker

Here是一個後關於如何做到這一點!

PS。請注意,如果您綁定的對象是ObservableCollection<> ...詳細瞭解我所做的這些問題here

2

我對這些技術人員沒有做任何工作,所以我不能說那個。但是,對我來說,這聽起來像是在阻止調用redraw()(或其等價物)的代碼中發生某種死鎖。調整窗口大小將強制重繪,但是當您更改某些內容時,重新繪製窗口的正常機制可能會被阻止。

是否有可能在您的代碼中有競爭條件?在輕負載的系統上,事情可能以正確的順序發生,但在負載較重的系統上,時間可能不同。也許這是觸發代碼中的僵局?

如果您可以附加調試器,請查看正在運行的線程。如果你可以看到每個線程正在等待什麼,並且還有什麼可以鎖定(你可以用Java來做到這一點,不知道你的應用程序),這可能會幫助你確定它將在哪裏死去。

1

大部分時間,select isn't broken(俗話說)。

它確實聽起來很像某種種族或死鎖,因爲@Herms suggests

你當然可以檢查MSDN的已知錯誤。根據你的代碼是什麼樣的,當我確實被一個bug困住時,我發現刪除代碼塊直到你留下最小的測試用例通常會有幫助。

0

在您的應用程序中沒有什麼奇怪的事情發生。依賴系統「停止工作」,因爲所有系統依賴的UI線程都很忙。這是關於不同Disparcher對象的優先級。我可以考慮使用後臺進程doe來延長操作時間,同時在UI線程中完成所有同步。 另外,可以幫助你實現DoEvent模式,從WinForms中知道(用於處理Windows隊列中的消息) 總而言之,你可以使用任務優先級(DispatcherPriority枚舉作爲Invoke/BeginInvoke方法的第一個參數) 應該記住,你在STA工作。另外,在Windows XP中使用ElementHost時,實際上會刪除硬件加速。嘗試使用.NET 3.5 SP1以某種方式修復它,但仍需要離開CPU才能進行渲染和調度。