Proper way to handle real-time data??

Oystein Bjorke 10 year бұрын 0
This discussion was imported from CodePlex

ericjzim wrote at 2012-10-10 20:32:

I've been playing around with OxyPlot and found it to almost be a certainty that I recieve a "Collection was modified; enumeration operation may not execute." exception if I try to pan / zoom while adding points to the graph in real time.

What is the proper way to refresh the plot while running?

What is the proper way to add points as to not cause this exception?

Best Regards,

Eric


objo wrote at 2012-10-10 23:07:

Hi Eric, OxyPlot is not locking the model while refreshing. I would like to keep the library simple and think thread synchronization should be handled in the client code (I guess the alternative is to add synchronization objects to every list in the plotmodel?). Please comment everyone that knows more about this than me :-) You could also create a minimal example that we can include in the library, and we will help to make it thread-safe!


Dave_Maff wrote at 2012-10-17 16:47:

So far, the safest way I have found of asynchronously updating a chart series is to add the points to the series from the point generating thread, using the UI dispatcher. Here is a view model which demonstrates this:
namespace MyPlot
{
	public class MyPlotViewModel : INotifyPropertyChanged
	{
		public MyPlotViewModel()
		{
			DataPlot = new PlotModel();

			DataPlot.Series.Add(new LineSeries()
			{
				Title = "Sin(x)",
				Points = new List<IDataPoint>()
			});

			m_userInterfaceDispatcher = Dispatcher.CurrentDispatcher;
			var thread = new Thread(new ThreadStart(AddPoints));
			thread.Start();

		}

		public void AddPoints()
		{
			var x = 0.0;
			var addPoints = true;
			while (addPoints)
			{
				try
				{

					m_userInterfaceDispatcher.Invoke(() =>
					{
						(DataPlot.Series[0] as LineSeries).Points.Add(new DataPoint(x, Math.Sin(x)));
						if (PropertyChanged != null)
						{
							DataPlot.InvalidatePlot(true);
						}

					});
				}
				catch (TaskCanceledException e)
				{
					addPoints = false;
				}
				x = x + 2 * Math.PI / 100;
				Thread.Sleep(10);
			}
		}

		public PlotModel DataPlot
		{
			get; set;
		}

		public event PropertyChangedEventHandler PropertyChanged;

		private Dispatcher m_userInterfaceDispatcher;
	}
}

objo wrote at 2012-10-17 23:25:

Thanks for the example Dave!

Also see the new example using TPL (Examples/Wpf/WpfExamples/Examples/TaskDemo).
I tried to update the plot in a task running with the SynchronizationContext of the UI thread.


NejibCh wrote at 2013-03-09 15:27:

Thanks Dave for the example. I tried to implement it but it shows me the below error. Any idea please. Appreciate your help.

Error 3 Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type