To follow up on your dotTrace data : take a close look at those numbers. 138 calls to OnPaint over ~8 seconds (58ms to draw the chart). Also note that you've called BeginInvoke 2630 times! update_logging_stats
was handled over 2000 times - your polling thread seems to be running way too fast. It's feeding work to the UI thread faster than your eyes can see or the display can even render.
Since you call update_logging_stats
once for every time you've updated the chart, this means that your Windows message queue has accumulated an enormous backlog of paint messages and cannot keep up with them all (this is causing your UI thread to choke). You're simply giving it too much work to do (way more than is necessary). While it is busy drawing the chart, twenty more messages have come in to paint it again. Eventually it ends up trying to service the queue and locks up.
What you may try is something like adding a stopwatch and metering your demands on the chart - only send it an update every 200ms or so :
private void polling_thread_DoWork(object sender, DoWorkEventArgs e)
{
string sensor_values;
Thread.CurrentThread.Name = "polling";
Stopwatch spw = new Stopwatch();
spw.Restart();
while (true)
{
sensor_values = poll_the_sensors_and_collect_the_responses();
if (spw.ElapsedMilliseconds > 200)
{
chart_form.BeginInvoke(chart_form.update_chart_delegate,
new object[] { sensor_values });
spw.Restart();
}
pps = compute_polling_performance();
BeginInvoke(update_stats_delegate, new object[] {pps.ToString("00")});
}
}
You can still keep all of the data, of course, if you really need it with such resolution - do something else with sensor_values
when you are not adding them to the chart (save them to an array, file, etc). You might even consider collecting a number of data points over a span of 200ms or so and then sending a cluster of points to plot at once (rather than trying to replot the whole set a hundred times per second) - again if you are really accumulating data at that speed.