Right - I've had a look at your code. The issue you're facing here is that you are doing everything on the UI thread - and you shouldn't do that. What I did was create a
BackgroundWorker
in which I read the data in and updated the
ObservableCollection
. I then marshalled the data back onto the UI thread in the collection changed event.
Here's your code changed as I mentioned:
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using System.IO;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Threading;
using System.Collections.Specialized;
namespace RealTimeGraph
{
public partial class MainWindow : Window
{
public string FullNamePath = @"C:\KarlSample\RealTimeGraph\michael-forks20101201-200256";
private double xmin = 0;
private double xmax = 1600;
private double ymin = 850;
private double ymax = 950;
private BackgroundWorker _bw = new BackgroundWorker();
Polyline pl;
ObservableCollection<Point> Obdatapoints = new ObservableCollection<Point>();
public MainWindow()
{
InitializeComponent();
_bw = new BackgroundWorker();
_bw.DoWork += new DoWorkEventHandler(_bw_DoWork);
}
void _bw_DoWork(object sender, DoWorkEventArgs e)
{
int count = 0;
string wrkString = null;
double[] values = new double[4];
StreamReader sr = new StreamReader(FullNamePath);
while ((wrkString = sr.ReadLine()) != null)
{
System.Threading.Thread.Sleep(500);
if (wrkString.StartsWith("\""))
{
wrkString = sr.ReadLine();
}
else
{
values = ParseTextStream(wrkString);
Point pt = new Point(count, values[0]);
Obdatapoints.Add(pt);
count++;
}
}
}
void Obdatapoints_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
this.Dispatcher.Invoke( DispatcherPriority.DataBind, new Action(()=>{
pl = CreateNewPolyLine(Obdatapoints);
GraphCanvas.Children.Add(pl);
}));
}
public double[] ParseTextStream(string wrkString)
{
string[] stringSeparators = new string[] { "," };
string[] sresult = new string[10];
double[] result = new double[4];
sresult = wrkString.Split(stringSeparators, StringSplitOptions.None);
result[0] = Double.Parse(sresult[1]);
result[1] = Double.Parse(sresult[2]);
result[2] = Double.Parse(sresult[7]);
result[3] = Double.Parse(sresult[8]);
return result;
}
private Point NormalizePoint(Point pt)
{
Point result = new Point();
result.X = ((pt.X - xmin) * GraphCanvas.Width / (xmax - xmin));
result.Y = GraphCanvas.Height - (pt.Y - ymin) * GraphCanvas.Height / (ymax - ymin);
return result;
}
public void chartGrid_SizeChanged(Object sender, SizeChangedEventArgs e)
{
if (pl == null) return;
GraphCanvas.Width = graphGrid.ActualWidth;
GraphCanvas.Height = graphGrid.ActualHeight;
GraphCanvas.Children.Clear();
GraphCanvas.Children.Add(pl);
}
public Polyline CreateNewPolyLine(ObservableCollection<Point> obdpts)
{
Polyline pltemp = new Polyline();
pltemp.Stroke = Brushes.Red;
pltemp.StrokeThickness = .5;
foreach (Point pt in obdpts)
{
pltemp.Points.Add(NormalizePoint(pt));
}
return pltemp;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Obdatapoints.CollectionChanged += new NotifyCollectionChangedEventHandler(Obdatapoints_CollectionChanged);
_bw.RunWorkerAsync();
}
}
}