在我的WPF应用程序中,我有一个填充了ObservableCollection集合的数据网格。假设我在网格中有这样的10个学生数据。每个学生都能够完成2个长时间运行的工作或处理,并将流程状态更新回网格。我想同时做那两个过程。所以我使用了Task和Parallel.Invoke方法。工作流程如下。
在开始按钮的点击事件中,我执行了以下代码。
foreach (Student stud in StudentLists)
{
stud.Status = "started..";
Task.Factory.StartNew(() => StartProcess(stud));
}
在StartProcess中,
Parallel.Invoke(() =>
{
MarkService ms = new MarkService(stud_data);
Student s = ms.GetMarkProcess(); // This will return the stud_data in the above line
Student studitem = StudentLists.Where(x => x.RollID == s.RollID).FirstOrDefault(); // find the student in the grid
if (studitem != null)
{
studitem.Status = "Mark Got it"; // if find, updating the status
}
},
() =>
{
SentMarks(poll); // this is another method to be executed parallel
}
);
当执行所有10个学生流程时,网格中的每个学生都成为相同的数据。 或者网格中只有2或1名学生显示“Mark Got it”状态。其他行仅显示“已启动...”状态。
为什么这不会更新集合。
我已经使用了INotofyPropertyChanged并在更新属性时激活了该事件。 在XAML中,每个绑定都以双向模式使用。
没有错误。但是学生集合中的1或2个项目有时会更新。有时,该集合包含所有9个项目的最后学生数据。
它不会更新网格中的确切学生对象。我的代码有什么问题?
在这种情况下有任何帮助???
答案 0 :(得分:0)
这里的问题是您从另一个线程引用UI控件。您应该创建一个内存数据结构,网格可以将其用作DataSource(实现IEnumerable的任何内容)。我建议将ConcurrentBag数据结构用于并行化代码(http://msdn.microsoft.com/en-us/library/dd997305.aspx)。一旦更新了ConcurrentBag中的每个学生记录,就可以将网格的数据源设置为该包。