2013-11-02 49 views
0

我最近開始使用MVVM Light Toolkit在MVVM模型上開發WPF。任務更新數據綁定OC不反映在UI上

我在listboxView中有一個列表框,它有一個listboxViewModel。在listboxViewModel中,我有一個ObseverableCollection(items),它在setter中引發一個PropertyChanged。

數據綁定到列表框是沒有問題的。

的問題是,當我嘗試使用任務異步從我的數據庫(在線來源)中提取數據,並更新項目,變化不會在UI反映。

但是,如果我要調用沒有任務的方法,導致UI凍結,直到數據到達我的界面,UI將反映這些更改。

我在任務中使用的代碼如下:

  Task.Factory.StartNew(() => 
      { 
       return new CCDatabase().CCDB; 
      }).ContinueWith(taskState => 
      { 
       items = taskState.Result; 
      }, TaskScheduler.Default); 

它只是沒有任何意義。我最好的猜測是它與任務的上下文有關。但是,當我在項目的setter中添加一個斷點時,該值是正確的,即5(5是我在數據庫中的表中的行數)。

我的問題是,如果我想要更新UI並同時獲得我的UI的好處,而不是每次調用數據庫時都會凍結,那怎麼辦呢。

我在VS2010編碼,所以我沒有獲得美妙的異步/等待神奇。我目前正在使用EntityFramework 6.0進行數據庫調用。

回答

0

在您的ContinueWith操作中,您傳遞的是default scheduler,它將從ThreadPool獲取調度程序。從MSDN文檔 -

的任務並行庫和PLINQ的默認調度使用 .NET框架線程池排隊和執行工作。

而且由於您無法從其他線程修改UI組件,因此無法在UI上進行更新。 取而代之的是使用TaskScheduler.FromCurrentSynchronizationContext(),它將爲您提供UI線程的調度程序並在UI線程上調度您的操作。

這將工作 -

 Task.Factory.StartNew(() => 
     { 
      return new CCDatabase().CCDB; 
     }).ContinueWith(taskState => 
     { 
      items = taskState.Result; 
     }, TaskScheduler.FromCurrentSynchronizationContext()); 
+0

我居然拿了考慮這一點,並試圖出來之前無濟於事。然而,問題是我有2個PropertyChanged事件,一個來自ViewModel繼承的ViewModelBase,另一個是我明確定義的。刪除額外的PropertyChanged事件及其相應的方法解決了問題。 我會記住你的答案,因爲它非常適用於ViewModel的上下文。在TaskScheduler.Default上運行它將不起作用。 –

+0

但是,如果您在默認調度程序上運行代碼,由於無法在後臺線程上修改UI對象,因此它將自動失敗。如果你試着繞着'items = taskState.Result'進行嘗試,你會看到異常被拋出,但不會使應用程序崩潰。但無論如何,如果它爲你工作,那麼它很好。 :) –