選項1:渲染事件
做你的計算上獨立的線程,但隊列更改UI和更新他們的渲染事件。它看起來像這樣:
PresentationSource.FromVisual(window).CompositionTarget.Rendering += (obj, e) =>
{
foreach(var update in _queue)
UpdateUI(update);
}
此代碼假定_queue是一個線程安全(同步)隊列。您可以創建這樣一個隊列類或下載一個隊列類。或者,您可以用「鎖定(_queue)」來包圍「foreach」。
這比Dispatcher.BeginInvoke()更好的原因是:1.它在每個幀之前被調用,所以如果幀速率下降,它會被調用得不那麼頻繁,2.它會批量處理更改。
選項2:多線程UI
您可以通過使用一個單獨的hWnd運行UI的一個單獨的線程的部分。您可以使用WindowsFormsIntegration或使用一些Win32魔術。這裏有一種方法:
- 在新線程中,構建窗口並顯示它(不要忘記Appliation。運行())
- 一旦顯示的新窗口,使用
((HwndSource)PresentationSource.FromVisual(window)).Handle
- 用監視器或ManualResetEvent的
- 使用WindowsFormsHost傳遞的hWnd回主UI線程構建HWND的容器中,添加得到的HWND它的UI
- 處理調整事件在主界面,通過他們下到包含的窗口
方案3:動畫
您可以創建自己的自定義動畫派生類來爲UI項目設置動畫。這些可以使用從模型中精確預測的數據。這樣做的好處是精確的時間同步:每次你的代碼被調用時,它都會確切地知道「何時」(在動畫時間內),它正在計算位置。因此,如果其他程序花費CPU或GPU一秒鐘,並減慢速度和幀速率,則動畫仍以較低的幀速率順利進行。
要做到這一點,子類DoubleAnimationBase
並重寫GetCurrentValueCore()來執行您的自定義計算,並結合所需的Clone()和CreateInstanceCore()覆蓋。然後用它來動畫你的屬性。
如果僅僅動畫現有對象的Double屬性是不夠的,則可以創建一個動畫來生成整個對象,如幾何,幾何三維,繪圖,Drawing3D甚至UIElement。爲此,子類AnimationTimeline和覆蓋GetCurrentValue()以及其他。
使用動畫的優點與渲染事件相同,除非您可以讓WPF爲您處理所有時鐘同步和重放速度問題,而不是自己做。如果您只能動畫改變的屬性,它也可能導致更少的代碼。
謝謝。我嘗試了選項3和1 - 並且...它工作) – ALOR 2010-03-03 21:41:40