Dispose pattern
When a chart has been created in code, and is no longer needed, chart.Dispose() should be called (first remove chart from collection it was added). It frees the chart and all its objects, such as series, markers and palette steps from the memory.
Extra care / ideal dispose pattern
While calling chart.Dispose() maybe sufficient for the most cases, user can improve GC (Garbage Collector - automated .NET memory handler) speed and avoid any uncertainties by applying The ideal dispose pattern as recommended by .NET/Microsoft.
Here is the complete list of steps user should take:
-
stop (or wait to finish) any background thread, which maybe streaming or pushing new data to the chart, before chart disposal.
-
Before chart is disposed unsubscribe from Events. Note this not only for Chart event like MouseClick, but also for any other events (e.g. axisX.RangeChanged, annotation.DraggedByUser, legend.MouseUp, series.MouseDown etc.)
-
Check that any class member, which references to chart (or it object) is properly updated or dispose. The example of such member is _pls = _chart.View3D.PointLineSeries[0] and it would be error dispose _pls, before removing it from chart/collection.
-
dispose and null chart.
Here is the example of dispose method of complex application (like ExampleEEGDataVisualizationShowcase from LightingChart Demo)
/// <summary>
/// Dispose charts.
/// </summary>
public void Dispose()
{
if (_backGroundWorker != null)
{
_running = false;
_backGroundWorker.Dispose();
_backGroundWorker = null;
}
if (_ChartList == null)
return;
// Remove first from UI.
ChartPlace3D.Children.Clear();
ChartPlaceEEG.Children.Clear();
ChartPlacePowerSpectrum.Children.Clear();
ChartHead2D0.Children.Clear();
ChartHead2D1.Children.Clear();
ChartHead2D2.Children.Clear();
ChartHead2D3.Children.Clear();
ChartHead2D4.Children.Clear();
// And dispose after removed from UI.
_ChartList[2].View3D.SurfaceMeshSeries3D[0].ContourPalette.Dispose();
for (int i = 0; i < _ChartList.Count; i++)
{
_ChartList[i].MouseClick -= Chart_MouseClick;
_ChartList[i].Dispose();
}
_ChartList = null;
_reader = null;
_spectrumCalculator.Dispose();
_spectrumCalculator = null;
_gads2D = null;
_sensorLocations = null;
_modelGeometryAdditionalData = null;
_dataPointSeries.Dispose();
_dataPointSeries = null;
_points = null;
_paletteStepColors = null;
_ThemeStepColors = null;
GC.Collect();
}
Disposing objects
If objects are created on the fly, and then the memory used by them needs to be freed before exiting the application or disposing the whole chart with chart.Dispose(), remove the object from the collection it has been added to, and then call Dispose() for the object.
For example, disposing a series from chart.ViewXY.PointLineSeries collection:
//Do cleanup... Remove and dispose 3 series
_chart.BeginUpdate();
List<PointLineSeries> listSeriesToBeRemoved = new List<PointLineSeries>();
listSeriesToBeRemoved.Add(_chart.ViewXY.PointLineSeries[1]);
listSeriesToBeRemoved.Add(_chart.ViewXY.PointLineSeries[3]);
listSeriesToBeRemoved.Add(_chart.ViewXY.PointLineSeries[4]);
foreach (PointLineSeries pls in listSeriesToBeRemoved)
{
_chart.ViewXY.PointLineSeries.Remove(pls);
pls.Dispose();
}
_chart.EndUpdate();
When LightingChart's objects are no longer needed, it is a good practice to dispose them to prevent memory leaking.
LightningChart’s collections also have specific methods for correctly disposing unused objects. Instead of calling generic list.Clear() method (e.g. ViewXY.SampleDataSeries.Clear()), RemoveAndDispose or DisposeAllAndClear can be used. For example, to remove all SampleDataSeries:
chart.ViewXY.SampleDataSeries.DisposeAllAndClear();