Как обновить элемент управления диаграммы C # с помощью привязки данных - PullRequest
3 голосов
/ 12 сентября 2011

У меня есть элемент управления C # Chart, и я связываю его с данными вот так.

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"

-Есть ли что-то, что я пропускаю до обновления? или я должен делать это по-другому, дайте мне знать, если вам нужна дополнительная информация.

Ответы [ 2 ]

3 голосов
/ 12 сентября 2011

Вам необходимо добавить блокировку или синхронизацию как в методе обновления , так и в методе DataBindXY.Вы не можете изменять List и читать его одновременно, потому что операции над Lists не являются потокобезопасными.

Я бы рекомендовал прочитать это (или одно из многих, многих других) введение в синхронизацию потоков в 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());
}
2 голосов
/ 12 сентября 2011

Элемент управления диаграммы считывает источник данных один раз (при выполнении вызова DataBindXY), что является причиной, по которой он не обновляется при изменении коллекции.

Причина, по которой вы получаете случайную проблему, заключается в том, что ваш фоновый поток, выполняющий обновление, изменяет коллекцию, когда диаграмма читает из нее.

Возможно, вам лучше иметь ось диаграммы в виде ObservableCollection, созданной в вашем потоке пользовательского интерфейса. Затем вы можете ответить на событие CollectionChanged, чтобы указать Chart DataBindXY.

ОДНАКО, чтобы использовать это правильно, фоновые потоки должны будут вызывать вызовы добавления к коллекции в потоке пользовательского интерфейса. Если у вас есть ссылка на chartcontrol, вы можете использовать вызов control.BeginInvoke.

...