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方法中的所有工作,这样我就可以显示进度条或类似的东西)
答案 0 :(得分:2)
我不相信你需要为这个Observable系列使用DP。最好将其存储在ViewModel中。
ObservableCollections不是线程安全的,您需要使用Dispatcher来更新集合。
谷歌有一些使用Dispatcher扩展到ObservableCollection的帖子。
答案 1 :(得分:1)
任何DependencyObject
都包含Dispatcher
属性,可以帮助您将工作推送到该对象的正确线程。
您可以使用Dispatcher.Invoke
或Dispatcher.BeginInvoke
在正确的主题上运行代码。
答案 2 :(得分:0)
唯一的解决方案似乎是在后台任务中不创建DependencyProperties(How to handle ObservableCollection<> result from a parallelized Task in MVVM?),这种奇怪的行为让我度过了最好的一天。但至少现在我知道问题所在。
答案 3 :(得分:0)
为了完整起见,我提到了WPF大师Dean Chalk的两个解决方案: