2

我有一個WPF應用程序,顯示一個ObservableCollection。它大約有182行,集合中的對象(我們稱之爲PositionLight)有大約70個屬性可以顯示。GUI凍結,而我更新我的ObservableCollection

所有計算這些性質的輸入數據在第二個線程將重計算的一切,每20個secondes,並將列表發送到WPF窗口,THX一個事件製成。這種計算不會減慢GUI。

這份名單是在與該事件的GIU發送的EventArgs的構造一個ObservableCollection轉化。

的問題是,即使我使用的BeginInvoke和委託辦:

myGUICollection = myEventArgsCollection

的圖形用戶界面將被凍結3到4秒......我已經投入了很多的Console.Writeline找出瓶頸在哪裏,但看起來凍結會在它離開BeginInvoke調用的函數後發生。我真的迷失在這裏。

我使用的是2.5Go RAM 4核PC,所以我不認爲這是一個硬件問題。

你們是否有一個想法?

一些代碼來給你在GUI中插入一個更好的主意:

public bool myCoreScope_OnCoreCalculationHandler(object myObject, CoreCalculationEventArgs myEventArgs) 
    { 

     foreach (PositionLight item in myEventArgs.MyPositionList) 
     { 
      lv.Dispatcher.BeginInvoke(new DisplayPositionItemCallBack(DisplayPositionItem), DispatcherPriority.Send, new object[] { item }); 
     } 

    } 


    private delegate void DisplayPositionItemCallBack(PositionLight item); 

    private void DisplayPositionItem(PositionLight item) 
    { 
     try 
     { 
      MyPositionList.Remove(MyPositionList.First(position => position.ID== item.ID)); 
     } 
     catch (Exception) 
     { } 
     MyPositionList.Add(item); 
    } 
+0

發佈一些更多的代碼來分析 – TalentTuner 2010-10-21 10:39:15

+0

@saurabh:done。我考慮了Fara所說的,但仍然以相同的凍結時間結束 – Gregfr 2010-10-22 04:00:09

回答

2

當你調用BeginInvoke你編組的ObservableCollection到GUI線程的更新,因此當計算可在發生一個單獨的線程UI的更新沒有。如果您在GUI線程上調用昂貴的更新,那麼線程將不得不等待該操作完成。

一種替代的方法是爲集合中的每個項目,而不是整個收集一次執行一個調用,這將給GUI的時間來更新之間處理其其他消息。

var list = GetCollection(); 
foreach (var item in list) 
{ 
    Dispatcher.BeginInvoke(new Action(() => myGuiCollection.Add(item))); 
} 

你可以嘗試另一種選擇是設置的ItemsSource數據綁定的屬性IsAsync

<ListBox ItemsSource="{Binding myGuiCollection, IsAsync=True}" /> 
+0

你說的確實有道理,但是,逐項添加項目意味着我首先找到舊項目,將其刪除,然後添加新項目一。恐怕不會加速這個過程。無論如何,我會試試 – Gregfr 2010-10-22 02:27:03

+0

GOT IT!我沒有刪除和插入新項目,而是逐個更新evry現有項目。它看起來像這樣使用更少的CPU,並且GUI不再被凍結。我會讓話題開放幾個小時,以確認它正常工作 – Gregfr 2010-10-22 06:30:04

+0

好的,我正在考慮更多關於初始化集合,而不是更新它。爲了更新綁定到UI的東西,你應該看看INotifyPropertyChanged接口。這是做這種事情的最佳方式。 – 2010-10-22 09:44:20