C#/ WPF数据绑定和后台工作者

时间:2011-08-16 11:43:55

标签: wpf multithreading xaml data-binding backgroundworker

UPDATE2

我已经重写了整个问题,因为有些事情变得更加清晰,现在的问题似乎是我在不同的线程上创建了一个DependencyProperties列表,而不是使用DependencyProperties :(。 / em>的

当我对BackgroundWorker XAML绑定做一些工作导致ArgumentException

  
    

必须在与DependencyObject相同的线程上创建DependencySource。

  

我有以下设置:

我有一个实现INotifyPropertyChanged的简单类,其中包含一些int,list和Dictionaries。

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的{​​{1}}文件中,我与UserControl有多个绑定,例如Calculator

(总体目标是能够在单独的线程上完成Calculate方法中的所有工作,这样我就可以显示进度条或类似的东西)

4 个答案:

答案 0 :(得分:2)

我不相信你需要为这个Observable系列使用DP。最好将其存储在ViewModel中。

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

谷歌有一些使用Dispatcher扩展到ObservableCollection的帖子。

This link might help

答案 1 :(得分:1)

任何DependencyObject都包含Dispatcher属性,可以帮助您将工作推送到该对象的正确线程。

您可以使用Dispatcher.InvokeDispatcher.BeginInvoke在正确的主题上运行代码。

答案 2 :(得分:0)

唯一的解决方案似乎是在后台任务中不创建DependencyProperties(How to handle ObservableCollection<> result from a parallelized Task in MVVM?),这种奇怪的行为让我度过了最好的一天。但至少现在我知道问题所在。

答案 3 :(得分:0)

为了完整起见,我提到了WPF大师Dean Chalk的两个解决方案:

  1. 创建一个线程安全的可观察集合。这是一个老派的解决方案。要获取源代码,请检查short article in his blog。这个帖子之前的anvarbek raupov提到了这个。类似的解决方案在Sasha Barber's blog
  2. 使用Reactive Extensions库。有关示例,请参阅this article。它对于一项任务来说有点笨重,但同时它带来了一堆现代工具,它们派上了用场。