SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, and iOS Chart & Android Chart Components

0 votes
220 views

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);
    }
Showing 1 result
This template supports the sidebar's widgets. Add one or use Full Width layout.