在將我的問題標記爲重複項之前,請聽我說。如何在長時間運行* UI *操作期間刷新UI
大多數人都有一個長時間運行的非UI操作,他們正在做,並需要解鎖UI線程。我有一個長時間運行的UI操作,其中必須在阻塞我的應用程序的其餘部分的UI線程上運行。基本上,我在運行時動態構建DependencyObject
,並將它們添加到我的WPF應用程序的UI組件上。需要創建的DependencyObject
的數量取決於用戶輸入,其中沒有限制。我有一個測試輸入有大約6000 DependencyObject
需要創建並加載它們需要幾分鐘。
在這種情況下使用後臺工作程序的常用解決方案不起作用,因爲一旦DependencyObject
由後臺工作程序創建,它們就不能再添加到UI組件,因爲它們是在後臺線程上創建的。
我目前的解決方案嘗試是在後臺線程中運行循環,爲每個工作單元分配UI線程,然後調用Thread.Yield()
爲UI線程提供更新機會。這幾乎奏效 - UI線程在操作過程中確實有機會更新自己,但應用程序仍然被阻止。
如何讓我的應用程序在這個長時間運行的操作過程中不斷更新UI和處理其他窗體上的事件?
編輯: 按照要求,我目前的「解決方案」的一個例子:
private void InitializeForm(List<NonDependencyObject> myCollection)
{
Action<NonDependencyObject> doWork = (nonDepObj) =>
{
var dependencyObject = CreateDependencyObject(nonDepObj);
UiComponent.Add(dependencyObject);
// Set up some binding on each dependencyObject and update progress bar
...
};
Action background =() =>
{
foreach (var nonDependencyObject in myCollection)
{
if (nonDependencyObject.NeedsToBeAdded())
{
Dispatcher.Invoke(doWork, nonDependencyObject);
Thread.Yield(); //Doesn't give UI enough time to update
}
}
};
background.BeginInvoke(background.EndInvoke, null);
}
更改Thread.Yield()
到Thread.Sleep(1)
似乎工作,但真正好的解決辦法?
發佈您的代碼的例子。 –
看來,主要問題是您需要創建的DependencyObjects的數量。在這種情況下,您可以嘗試將創建分解爲您在調度程序中排隊的多個任務。只要單個DependencyObject的創建不是太長時間運行,就可以以塊的形式處理它們,並保持UI的相應響應。 「如果我們將計算任務分解爲可管理的塊,我們可以定期返回調度程序並處理事件,我們可以給WPF一個重繪和處理輸入的機會。」 - http://msdn.microsoft.com/en-us/library/ms741870(v=vs.110).aspx – DavidN
'基本上,我在運行時動態構建DependencyObjects並將它們添加到我的WPF應用程序的UI組件' - 我一直在想如果你真的需要的是一個'ItemsControl'和一個合適的ViewModel。 –