It seems like a memory leak of sciChartSurface. After call Dispose(), some sciChartSurfaces are also refrenced by MouseManager and can’t release.
I also use ants memory profiler, but this web page can’t upload images and attachments, it alerts Forbidden!
The leak instance reference chain is:
MouseManager.I -> Dictionary<string,IList<Mouse.IReceiveMouseEvents>> -> SciChart.Core.Utility.Mouse.IReceiveMouseEvents[] -> SciChart.Charting.ChartModifiers.ModifierGroup -> SciChart.Charting.Visuals.SciChartSurface .
Below is the key code:
>
private SciChartSurface sciTickPriceChartSurface;
private FastLineRenderableSeries lastPriceLineRenderableSeries;
private SciChartSurface sciTickVolumeChartSurface;
private FastLineRenderableSeries volumeLineRenderableSeries;
private void LoadSciTickCharts()
{
// set sciTickPriceChartSurface xAxis
var nowDateTime = DateTime.Now;
var todayDate = nowDateTime.Date;
// set sciTickPriceChartSurface
sciTickPriceChartSurface = new SciChartSurface();
sciTickPriceChartSurface.ViewportManager = new TickChartViewportManager(todayDate);
var priceChartXAxis = new DiscontinuousDateTimeAxis
{
DrawLabels = false,
MajorDelta = new TimeSpan(1, 0, 0),
MinorDelta = new TimeSpan(0,12,0),
MinimalZoomConstrain = new TimeSpan(1,0,0),
AutoTicks = false,
DrawMajorGridLines = true,
DrawMinorGridLines = false,
AutoRange = AutoRange.Never,
LabelProvider = new TickDateTimeAxisLabelProvider(),
//Calendar = new LSECalendar(),
VisibleRange = new DateRange(nowDateTime - new TimeSpan(1,0,0), nowDateTime + new TimeSpan(3,0,0)),
};
sciTickPriceChartSurface.XAxes.Add(priceChartXAxis);
// set sciTickPriceChartSurface yAxis
var priceYAxis = new NumericAxis
{
DrawMajorGridLines = true,
DrawMinorGridLines = false,
AutoRange = AutoRange.Always,
GrowBy = new DoubleRange(0.2, 0.2)
};
sciTickPriceChartSurface.YAxes.Add(priceYAxis);
// lastPriceLineSeries
lastPriceLineRenderableSeries = new FastLineRenderableSeries
{
Stroke = Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF),
StrokeThickness = 1,
DataSeries = new XyDataSeries<DateTime, double>(),
};
sciTickPriceChartSurface.RenderableSeries.Add(lastPriceLineRenderableSeries);
CursorModifier.SetSnapToSeries(lastPriceLineRenderableSeries, true);
// sciTickVolumeChartSurface
sciTickVolumeChartSurface = new SciChartSurface();
// set sciTickVolumeChartSurface yAxis
var volumeYAxis = new NumericAxis
{
DrawMajorGridLines = true,
DrawMinorGridLines = false,
AutoRange = AutoRange.Always,
GrowBy = new DoubleRange(0, 0)
};
sciTickVolumeChartSurface.YAxes.Add(volumeYAxis);
var volumeChartXAxis = new DiscontinuousDateTimeAxis
{
DrawLabels = true,
MajorDelta = new TimeSpan(1, 0, 0),
MinorDelta = new TimeSpan(0, 12, 0),
MinimalZoomConstrain = new TimeSpan(1, 0, 0),
AutoTicks = false,
DrawMajorGridLines = true,
DrawMinorGridLines = false,
AutoRange = AutoRange.Never,
LabelProvider = new TickDateTimeAxisLabelProvider(),
//Calendar = new LSECalendar()
};
sciTickVolumeChartSurface.XAxes.Add(volumeChartXAxis);
// Bind the VisibleRange of chart2.XAxis.VisibleRange to chart1.XAxis.VisibleRange TwoWay
var xAxisVisibleRangeBinding = new Binding("VisibleRange")
{
Source = priceChartXAxis,
Mode = BindingMode.TwoWay,
};
BindingOperations.SetBinding(volumeChartXAxis, SciChart.Charting.Visuals.Axes.AxisBase.VisibleRangeProperty, xAxisVisibleRangeBinding);
// volumeLineSeries
volumeLineRenderableSeries = new FastLineRenderableSeries
{
Stroke = Color.FromArgb(0xFF, 0x0, 0xFF, 0xFF),
StrokeThickness = 1,
DataSeries = new XyDataSeries<DateTime, long>(),
};
sciTickVolumeChartSurface.RenderableSeries.Add(volumeLineRenderableSeries);
CursorModifier.SetSnapToSeries(volumeLineRenderableSeries, true);
var grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(2, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
var gridSplitter = new GridSplitter
{
MinHeight = 4,
HorizontalAlignment = HorizontalAlignment.Stretch,
Background = new SolidColorBrush(Color.FromRgb(0xFF, 0xFF, 0x0))
};
Grid.SetRow(sciTickPriceChartSurface, 0);
Grid.SetRow(gridSplitter, 1);
Grid.SetRow(sciTickVolumeChartSurface, 2);
grid.Children.Add(sciTickPriceChartSurface);
grid.Children.Add(gridSplitter);
grid.Children.Add(sciTickVolumeChartSurface);
var priceChartSurfaceModifier = new ModifierGroup(
// Allow pan on Left mouse drag
new ZoomPanModifier { ExecuteOn = ExecuteOn.MouseLeftButton, ClipModeX = SciChart.Charting.ClipMode.None },
// <!-- Allow Mousewheel Zoom -->
new MouseWheelZoomModifier(),
// <!-- Allow Zoom to Extents on double click -->
new TickChartZoomExtentsModifier { ExecuteOn = ExecuteOn.MouseDoubleClick },
// Alow cursor modifier
new CursorModifier
{
SourceMode = SourceMode.AllSeries,
ShowTooltipOn = ShowTooltipOptions.Always,
ShowAxisLabels = true,
ReceiveHandledEvents = true,
ShowTooltip = true,
IsEnabled = true,
}
);
sciTickPriceChartSurface.ChartModifier = priceChartSurfaceModifier;
var volumeChartSurfaceModifier = new ModifierGroup(
// Allow pan on Left mouse drag
new ZoomPanModifier { ExecuteOn = ExecuteOn.MouseLeftButton, ClipModeX = SciChart.Charting.ClipMode.None },
// <!-- Allow Mousewheel Zoom -->
new MouseWheelZoomModifier(),
// <!-- Allow Zoom to Extents on double click -->
new TickChartZoomExtentsModifier { ExecuteOn = ExecuteOn.MouseDoubleClick },
// Alow cursor modifier
new CursorModifier
{
SourceMode = SourceMode.AllSeries,
ShowTooltipOn = ShowTooltipOptions.Always,
ShowAxisLabels = true,
ReceiveHandledEvents = true,
ShowTooltip = true,
IsEnabled = true,
}
);
sciTickVolumeChartSurface.ChartModifier = volumeChartSurfaceModifier;
var tickChartsMouseEventSharedGroupName = UUIDHelper.CreateUUIDString(false).ToString();
MouseManager.SetMouseEventGroup(priceChartSurfaceModifier, tickChartsMouseEventSharedGroupName);
MouseManager.SetMouseEventGroup(volumeChartSurfaceModifier, tickChartsMouseEventSharedGroupName);
var tickChartSharedGroupName = UUIDHelper.CreateUUIDString(false).ToString();
SciChartGroup.SetVerticalChartGroup(sciTickPriceChartSurface, tickChartSharedGroupName);
SciChartGroup.SetVerticalChartGroup(sciTickVolumeChartSurface, tickChartSharedGroupName);
this.ChartGrid.Children.Clear();
this.ChartGrid.Children.Add(grid);
}
public void Dispose()
{
if (isDisposed == true) return;
isDisposed = true;
// Don't forget to clear chart grid child list.
ChartGrid.Children.Clear();
if (sciTickPriceChartSurface != null)
{
// Chart's Dispose method needs to be called when chart is
// no longer needed so that all unmanaged resources
// (DirectX etc.) are released.
sciTickPriceChartSurface.ChartModifier?.OnDetached();
sciTickPriceChartSurface?.Dispose();
sciTickPriceChartSurface = null;
}
if (sciTickVolumeChartSurface != null)
{
// Chart's Dispose method needs to be called when chart is
// no longer needed so that all unmanaged resources
// (DirectX etc.) are released.
sciTickVolumeChartSurface?.ChartModifier?.OnDetached();
sciTickVolumeChartSurface?.Dispose();
sciTickVolumeChartSurface = null;
}
GC.SuppressFinalize(this);
}
- Peng GuangBo asked 5 years ago
- last edited 5 years ago
- You must login to post comments
Hi there,
Under normal operation, there is no need to call SciChartSurface.Dispose(), as SciChartSurface implements the Finalizer pattern and will automatically clear its resources when the chart is garbage collected.
However, you have set MouseManager.MouseEventGroup attached property, which causes two surfaces to be linked together (in static dictionary as you have discovered with ANTS). This may prevent garbage collection in the first place. You can try to unset this property (set to null) when the surface is no longer needed. Can you try that?
Finally – I am testing image attachments
Best regards,
Andrew
- Andrew Burnett-Thompson answered 5 years ago
- You must login to post comments
Please login first to submit.