我有一个C#Chart Control,我的数据绑定就像这样。
chart.Series[0].Points.DataBindXY(xAxis, yAxis);
where xAxis is List<String> and yAxis is List<Double>
在另一个线程上xAxis和yAxis不断更新(多次调用.Add())
然而,除非我再次调用DataBindXY(),否则图表不会更新,但这似乎会导致问题,因为我每次都会得到
Error: "Collection was modified; enumeration operation may not execute."
在某些时候导致我的程序崩溃
Error: "system.reflection.targetinvocationexception' occurred in mscorlib.dll"
- 就更新问题而言,我有什么遗漏?或者我应该这么做,请告诉我你是否需要更多信息。
答案 0 :(得分:3)
您需要在更新方法 和 DataBindXY方法中添加锁定或同步。您无法修改List并同时读取它,因为列表上的操作不是线程安全的。
我建议您阅读C#中关于线程同步的这个(或许多其他的一个)介绍:http://msdn.microsoft.com/en-us/library/ms173179.aspx
编辑:以下是如何执行此操作的示例:
Object lockOnMe = new Object();
... in your Add loop
(int i = 0; i < dacPoints.Count; i += 1) {
TimeSpan span = new TimeSpan(0, 0, i + 1);
lock (lockOnMe) {
presenter.addPoint(span.ToString(), dacPoints[i]);
}
System.Threading.Thread.Sleep(200);
}
... when calling DataBindXY()
lock (lockOnMe) {
// Note that I copy the lists here.
// This is because calling DataBindXY is not necessarily a serial,
// blocking operation, and you don't want the UI thread touching
// these lists later on after we exit the lock
chart.Series[0].Points.DataBindXY(xAxis.ToList(), yAxis.ToList());
}
答案 1 :(得分:2)
图表控件读取数据源一次(当您发出DataBindXY调用时),这是修改集合时不更新的原因。
您偶然遇到问题的原因是因为您正在进行更新的后台线程正在更改集合,因为图表正在从中读取。
您可能最好将图表轴作为在UI线程上创建的ObservableCollection。然后,您可以响应CollectionChanged事件以指示Chart to DataBindXY。
但是,为了正确使用它,您的后台线程将需要在UI线程上调用对集合的add调用。如果您有对chartcontrol的引用,则可以使用control.BeginInvoke调用。