Profile Picture

OutOfMemoryException on WPF chart

Posted By Kianoosh Ahmadi 5 Years Ago
Author
Message
Kianoosh Ahmadi
Posted 5 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)

Group: Forum Members
Last Active: 5 Years Ago
Posts: 3, Visits: 111
SnippetHi, I have a WPF page that shows a chart with multiple line series, recently I got 'UnhandledException' exception error written in log file, and whole application shut downed, actually it happened multiple times before, here is the exception detail :


Type: System.OutOfMemoryException
Message: Out of memory.
StackTrace: 
at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
 at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32 width, Int32 height)
 at System.Drawing.Graphics.DrawImage(Image image, Rectangle rect)
 at Nevron.Chart.Wpf.NWpfGdiRenderSurface.Paint(DrawingContext context, NWpfChartControlView view)
 at Nevron.Chart.Wpf.NWpfChartControlView.Paint(DrawingContext drawingContext)
 at Nevron.Chart.Wpf.NChartControl.OnRender(DrawingContext drawingContext)
 at System.Windows.UIElement.Arrange(Rect finalRect)
 at System.Windows.ContextLayoutManager.UpdateLayout()
 at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg)
 at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork()
 at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
 at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
 at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
 at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
 at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
 at System.Windows.Threading.DispatcherOperation.InvokeImpl()
 at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
 at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
 at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
 at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
 at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
 at System.Windows.Threading.DispatcherOperation.Invoke()
 at System.Windows.Threading.Dispatcher.ProcessQueue()
 at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
 at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
 at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
 at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
 at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
 at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
 at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
 at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
 at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
 at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
 at System.Windows.Application.RunDispatcher(Object ignore)
 at System.Windows.Application.RunInternal(Window window)
 at System.Windows.Application.Run(Window window)
 at System.Windows.Application.Run()
 at MyChartApp.App.Main()


I was wondering what causes 'out of  memory' exception error?

Here is my code:



internal partial class ChartView
  {
   public ChartView()
   {
_lines = new NLineSeries[Vm.GraphOptions.Count];
    _axis = new NAxis[Vm.GraphOptions.Count];

CreateChart();

t = new DispatcherTimer {Interval = TimeSpan.FromSeconds(1)};
    t.Tick += (s, e) =>
    {
      try
      {
       GenerateLabels();
      
       for (var i = 0; i < Vm.GraphOptions.Count; i++)
       {
        _lines[i].Visible = Vm.GraphOptions[i].IsChecked;
        _axis[i].Visible = Vm.GraphOptions[i].IsChecked;
       }

       NChartControl1.Refresh();
      }
      catch (Exception ex)
      {
       SystemLog.WriteLine(ex);
      }
    };
    t.Start();
}




public void CreateChart()
   {
    NChartControl1.Charts.Clear();
    NChartControl1.Charts.Add(new NCartesianChart());
    _chart = (NCartesianChart)NChartControl1.Charts[0];
    NChartControl1.DataBindingManager.EnableDataBinding = true;

    NChartControl1.Legends.Clear();
    NChartControl1.BackgroundStyle.FrameStyle.Visible = false;

    _chart.DockMode = PanelDockMode.Fill;
    _chart.BoundsMode = BoundsMode.Stretch;
    _chart.Padding = new NMarginsL(0);
    _chart.Margins = new NMarginsL(5, 10, 5, 5);

    _chart.Axis(StandardAxis.PrimaryY).Visible = false;
    _chart.Axis(StandardAxis.SecondaryY).Visible = false;
    _chart.Axis(StandardAxis.PrimaryX).ScaleConfigurator = new NLinearScaleConfigurator();

    var linearScale = new NLinearScaleConfigurator(); ;
    linearScale.RulerStyle.BorderStyle.Color = Color.White;

    _chart.Axis(StandardAxis.PrimaryY).ScaleConfigurator = linearScale;
    _chart.Axis(StandardAxis.SecondaryY).ScaleConfigurator = linearScale;

    int i = 0;
    foreach (var cr in Vm.GraphOptions)
    {
      var axis = CreateAxis(_chart, true, 0, 100, 0, GetCurveMax(cr.DisplayName), cr.DisplayName, GetCurveColor(cr.DisplayName));
      var line = CreateLineSeries(GetCurveColor(cr.DisplayName));
      _chart.Series.Add(line);
      line.DisplayOnAxis(StandardAxis.PrimaryY, false);
      line.DisplayOnAxis(StandardAxis.SecondaryY, false);
      line.DisplayOnAxis(axis.AxisId, true);
      _axis[i] = axis;
      _lines[i] = line;
      i++;
    }

    GenerateLabels();

    BindingChartToData();

    var sc = (NLinearScaleConfigurator)_chart.Axis(StandardAxis.PrimaryX).ScaleConfigurator;
    sc.Title.Text = "min";
    sc.MajorGridStyle.SetShowAtWall(ChartWallType.Back, true);
    sc.MajorGridStyle.LineStyle.CustomPattern = 0x5555;
    sc.MajorGridStyle.LineStyle.Factor = 2;
    sc.MajorGridStyle.LineStyle.Color = Color.White; // Color.Gray;
    sc.MajorGridStyle.LineStyle.Width = new NLength(0.5f, NGraphicsUnit.Point);
    sc.MajorGridStyle.LineStyle.Pattern = LinePattern.Custom;

    NChartControl1.Refresh();
   }


private static NLineSeries CreateLineSeries(Color color)
   {
    var line = new NLineSeries
    {
      UseXValues = true,
      DataLabelStyle = { Visible = false },
      BorderStyle = { Color = color, Width = new NLength(2) },
      SamplingMode = SeriesSamplingMode.Enabled,

    };
    return line;
   }


private static NAxis CreateAxis(NCartesianChart chart, bool createLevel, float beginPercent, float endPercent, double min, double max, string title, Color color)
   {
    NAxis axis = ((NCartesianAxisCollection)chart.Axes).AddCustomAxis(AxisOrientation.Vertical, AxisDockZone.FrontLeft);
    axis.Visible = true;
    axis.Anchor.BeginPercent = beginPercent;
    axis.Anchor.EndPercent = endPercent;
    ((NDockAxisAnchor)axis.Anchor).CreateNewZoneLevel = createLevel;

    axis.View = new NRangeAxisView(new NRange1DD(min, max), true, true);

    var linearScale = new NLinearScaleConfigurator();
    linearScale.MajorTickMode = MajorTickMode.CustomTicks;
    linearScale.CustomMajorTicks.Add(min);
    linearScale.CustomMajorTicks.Add(max);
    linearScale.Title.Text = title;
    linearScale.Title.TextStyle.FillStyle = new NColorFillStyle(color);
    linearScale.RulerStyle.BorderStyle.Color = color;
    linearScale.InnerMajorTickStyle.LineStyle.Color = color;
    linearScale.OuterMajorTickStyle.LineStyle.Color = color;
    linearScale.LabelStyle.TextStyle.FillStyle = new NColorFillStyle(color);

    linearScale.CustomStep = max / 10;
    linearScale.MajorTickMode = MajorTickMode.CustomStep;
    linearScale.MajorGridStyle.SetShowAtWall(ChartWallType.Back, true);
    linearScale.MajorGridStyle.LineStyle.CustomPattern = 0x5555;
    linearScale.MajorGridStyle.LineStyle.Factor = 2;
    linearScale.MajorGridStyle.LineStyle.Color = Color.White; // Color.Gray;
    linearScale.MajorGridStyle.LineStyle.Width = new NLength(0.5f, NGraphicsUnit.Point);
    linearScale.MajorGridStyle.LineStyle.Pattern = LinePattern.Custom;

    axis.ScaleConfigurator = linearScale;

    return axis;
   }



private void GenerateLabels()
   {
    try
    {
      _scaleConfiguratorX = (NLinearScaleConfigurator) _chart.Axis(StandardAxis.PrimaryX).ScaleConfigurator;

      double start = 0.0;
      double end = 0.0;

      lock (LockTimeBasedPoints)
      {
       var count = TimeBasedPoints.Rows.Count - 1;
       if (count <= 0) return;
       end = double.Parse(TimeBasedPoints.Rows[count]["X"].ToString());
      }

      _scaleConfiguratorX.MajorTickMode = MajorTickMode.CustomStep;
      var step = end/20;
      if (step < 1) step = 1;
      step = Math.Round(step, 0);
      _scaleConfiguratorX.CustomStep = step;
    }
    catch (Exception ex)
    {
      SystemLog.WriteLine(ex);
    }

   }



private void BindingChartToData()
   {
    int i = 0;
    foreach (var cr in Vm.GraphOptions)
    {
      NChartControl1.DataBindingManager.AddBinding(0, i, "XValues", TimeBasedPoints, "X");
      NChartControl1.DataBindingManager.AddBinding(0, i, "Values", TimeBasedPoints, GetMinName(cr.DisplayName));
      i++;
    }
    NChartControl1.DataBindingManager.UpdateChartControl();
   }

}



I have maximum 100 data point per second for each line series, and maximum 12 line series will be shown at the same chart.
chart will refresh every second in a timer.
by the way this exception wont happen a lot, only some days.


Nevron Chart : 16.9.27.12 (WPF)
.NET : 4.5.1



Nevron Support
Posted 5 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)

Group: Forum Members
Last Active: Last Year
Posts: 3,039, Visits: 3,746
Hi Kianoosh,

We haven't been able to replicate such a problem with the new version - have you tested with the most recent release whether you still experience it? Also please send us an app that replicates the problem at support@nevron.com as the below code does not compile - if we manage to replicate the problem it will be fixed as soon as possible.



Best Regards,
Nevron Support Team



Kianoosh Ahmadi
Posted 5 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)

Group: Forum Members
Last Active: 5 Years Ago
Posts: 3, Visits: 111
I'm using version 2016, but I will try newer version. As I said before this exception comes very rarely, like once a week, but it's annoying and need to fix it. I was hoping you could tell me whats wrong by seeing StackTrace of the exception. Anyway I already sent you an email with a simplified version of my program attached to it. Thanks in advanced.

Nevron Support
Posted 5 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)

Group: Forum Members
Last Active: Last Year
Posts: 3,039, Visits: 3,746
Hi Kianoosh,
We were not able to reproduce the problem with the chart itself. However we noticed that you're constantly adding data rows to the table and they are never deleted. This will surely cause memory problems at some point...

Best Regards,
Nevron Support Team



Kianoosh Ahmadi
Posted 5 Years Ago
View Quick Profile
Forum Newbie

Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)Forum Newbie (9 reputation)

Group: Forum Members
Last Active: 5 Years Ago
Posts: 3, Visits: 111
I'm sorry, the code I sent you was a portion of my bigger program, that I couldn't send, but the rows in DataTable will get deleted at some point. There will be at most 7500 rows or about 100,000 data points that will be bind to chart. I think NOV Chart can handle that much. However, is there any other way, other than DataTable, to bind to chart?
Is it possible that showing a lot of data points in a single chart without zooming or scrolling leads to 'out of memory' exception? 
I'm saying this because as I adding more rows to the table it will take longer to refresh chart.
and one more question:
All my data points are type 'double', What will happen if we give a NaN (not a number) or a Infinity value as a data point to the chart? How NOV chart handle those values?

Nevron Support
Posted 5 Years Ago
View Quick Profile
Supreme Being

Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)Supreme Being (4,329 reputation)

Group: Forum Members
Last Active: Last Year
Posts: 3,039, Visits: 3,746
Hi Kianoosh,
We would like to first rule out the possibility that this is a purely GDI+ (MS) problem. For this purpose please run the app in hardware accelerated mode:
nChartControl1.Settings.RenderSurface = RenderSurface.Window;
if it does not throw an exception after a week or so then this is a GDI+ problem. Let us know if the problem persists...

Best Regards,
Nevron Support Team





Similar Topics


Reading This Topic