Click here to Skip to main content
15,885,985 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am trying to model a multi line chart using chartingToolkit library in Wpf. The graph/chart has to run for atleast 8 -10 hrs. There is problem of linear process memory Increase (upto 800 MB or more). I need to plot real time data from serial Com Port (different slaves). I am calling 2 process UpadateValue and UpdateChart from DispatcherTimer.


While running this program, Process memory increases linearly with time (more than 900Mb observed from Task Manager..!!).

Please suggest me some things to resolve memory issue.

Thanks a Lot

What I have tried:

public partial class MainWindow : Window
{
ObservableCollection<KeyValuePair<int, int>> Collection0 = new ObservableCollection<KeyValuePair<int, int>>();
ObservableCollection<KeyValuePair<int, int>> Collection1 = new ObservableCollection<KeyValuePair<int, int>>();
/*..........continue.............*/
ObservableCollection<KeyValuePair<int, int>> Collection39 = new ObservableCollection<KeyValuePair<int, int>>();

Random rnd = new Random();
public int i = 0;

public MainWindow()
{
InitializeComponent();

Parallel.Invoke(() => { SetTimer1(); });
Parallel.Invoke(() => { SetTimer2(); });
}

private void SetTimer1()
{
DispatcherTimer dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(ValueUpdate);
dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 2, 0);
dispatcherTimer.Start();
}

private void SetTimer2()
{
DispatcherTimer dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(ChartUpdate);
dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 2, 0);
dispatcherTimer.Start();
}

private void ValueUpdate(object sender, EventArgs e)
{
int m = -40;
GC.Collect();
Collection0.Add(new KeyValuePair<int, int>(i, rnd.Next(m++, m++)));
Collection1.Add(new KeyValuePair<int, int>(i, rnd.Next(m++, m++)));
/*......continue......*/
Collection39.Add(new KeyValuePair<int, int>(i, rnd.Next(m++, m++)));
i = i + 1;
GC.Collect();

}

void ChartUpdate(object sender, EventArgs e)
{
GC.Collect();
LineChart0.DataContext = Collection0;
LineChart1.DataContext = Collection1;
/*.....continue.....*/
LineChart39.DataContext = Collection39;
GC.Collect();
}
}
Posted
Updated 11-Sep-18 22:40pm

1 solution

Interesting problem - but the solution is quit difficult to achieve:

1) One way to handle the memory problem is to go over your time series in regular intervals and through out details, say you look at every point within 5 seconds and you average over those 5 points and replace them with the average value that you saw
- this results in less detail but might be OK if you just need a general trend and you would free memory of 4 data-points using only 1 data point in the result

2) When I think about your problem it sounds more like a data problem then a WPF problem. So, one other 'obvious' solution is to dump your datapoints into a storage (SQLite of SQL Server) that is large and fast enough and then have you control display only a limited/finit part of that data series. That way, you loos no data and can always work on different ways of displaying results - for instance showing averaged data when the user zooms out or showing details when you zoom in.

Its a lot of work and not easy to implement but quit interesting - hope it helps.
 
Share this answer
 
Comments
Member 13980927 13-Sep-18 10:11am    
Thanks for a quick reply. The requirement is to show data for a duration of 8 hrs(from the starting point). Your second point seems good, could I dump the serial data to database and show the whole data every 5 seconds on to the chart?
Dirk Bahle 13-Sep-18 15:46pm    
Yes, thats what I had in mind, you could, depending on the number of your data points and the number of points you need to show build different levels of aggregated/averaged views - Say, you have a detailled table with the raw data (level 0), then you could have a level 1 data table where every data point in level 1 represents the average value of the last 100 data points in the level 0 table.

Depending on your need you could average over 1000 instead of 100 points or you could use multiple levels of aggregated tables level 0, level 1, level 3 ... where the first table contains all the raw data and every other table averaged values over 100 points in level 0, 100 points averaged over level 1 ...

'Obviously', youre tables will get smaller as the level 0,1,2 ... increases and you can also support different views of details in your chart. The update should be much difficult either since you would compute the averages only every 100 or so record...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900