2011-08-16 66 views
1

UPDATE2C#/ WPF數據綁定和backgroundworkers

我已經重寫了整個問題,因爲有些事情變得更加清晰,這個問題現在似乎是我創建了一個不同的線程DependencyProperties列表比在該DependencyProperties將用於:(。

當我做一個BackgroundWorkerXAML綁定一些工作造成ArgumentException

必須在與DependencyObject相同的線程上創建DependencySource。

我有以下設置:

我有一個簡單的類,它實現INotifyPropertyChanged其中包含了幾個整數,列表的和字典。

public class Calculator : INotifyPropertyChanged 
{ 
    //Note that InstanceGroup is a dependency object 
    private List<InstanceGroup> instanceGroups = new List<InstanceGroup>(); 
    public List<InstanceGroup> InstanceGroups 
    { 
     get { return instanceGroups; } 
     set { instanceGroups = value; } 
    } 

    // snip // 

    public void Calculate() 
    { 
     InstanceGroups = MyNewFilledInstanceGroup; 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("instanceGroups")); 
      } 
    } 
} 

UserControl我使用BackgroundWorker運行Calculate方法,因爲它會佔用大量的時間:

BackgroundWorker worker = new BackgroundWorker(); 
worker.DoWork += delegate(object o, DoWorkEventArgs args) 
{ 
    lock (Calculator) 
    {  
     Calculator.Calculate(); 
    } 
}; 
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); 
worker.RunWorkerAsync(); 

XAML文件UserControl我有多個綁定到Calculator ,如{Binding Path=Calculator.InstanceGroups, Path=userControlName}

(總的目標是能夠做所有的工作在計算方法上的一個單獨的線程,所以我可以顯示一個進度條或類似的東西)

回答

2

我不相信你需要使用DP爲這個Observable集合。最好將其存儲在ViewModel中。

ObservableCollections不是線程安全的,您需要使用Dispatcher更新集合。

谷歌有一些擴展到ObservableCollection使用分派器的職位。

This link might help

+0

嘿Anvarbek,我(暫時)用正常的List <>替換ObservableCollection,但問題依然存在。 –

0

任何DependencyObject包括Dispatcher特性,可以幫助你推動工作,該對象的正確的線程。

您可以使用Dispatcher.InvokeDispatcher.BeginInvoke在正確的線程上運行代碼。

0

爲了完整起見,我會提到WPF大師Dean Chalk的兩個解決方案:

  1. 創建一個線程安全的觀察的集合。這是一個老派的解決方案,只是起作用。要獲取源代碼,請檢查short article in his blog。這個線索早些時候由anvarbek raupov提到。類似的解決方案在Sasha Barber's blog
  2. 使用Reactive Extensions庫。一個例子見this article。這對於一項任務來說有點笨重,但同時它帶來了一些現代工具。