ni.com is currently undergoing scheduled maintenance.

Some services may be unavailable at this time. Please contact us for help or try again later.

Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

WPF Graph thread issue

Solved!
Go to solution

Hi,

 

We are using binding on the Datasource and update the binded data in a thread. Similar to the issues described in M16525, but even though we are using the dispatcher to invoke the main thread it seems we sometimes get a race condition. I have created a simple example using a timer to illustrate the issue. I have set the timer frequency high to quickly provoke the error. Are we doing something wrong or is it not possible to update safe in a thread calling back to main thread? The error we get is “System.Reflection.TargetInvocationException: 'Exception has been thrown by the target of an invocation.'”

 

Example (Doesn’t fail each time, but fails on startup if you start it a couple of times):

 

public partial class MainWindow : Window

{

   private Random rand;

   private ObservableCollection<ChartCollection<DateTime, double>> trendData;

   private Timer timer;

   public MainWindow()

   {

      InitializeComponent();

 

      rand = new Random();

      trendData = new ObservableCollection<ChartCollection<DateTime, double>>();

      trendData.Add(new ChartCollection<DateTime, double>(10000));

 

      DataContext = this;

 

      this.timer = new Timer(OnTimerElapsed);

      this.timer.Change(0, 10);

   }

 

   private void OnTimerElapsed(object stat)

   {

      this.Dispatcher.Invoke(

       new Action(() => { plot(); }));

   }

 

   private void plot()

   {

      trendData[0].Append(DateTime.Now, 10 * rand.NextDouble());

   }

 

   public ObservableCollection<ChartCollection<DateTime, double>> TrendData

   {

      get => this.trendData;

   }

}

 

XAML:

<Grid>

   <ni:Graph DataSource="{Binding TrendData}" RenderMode="Raster">

   </ni:Graph>

</Grid>

0 Kudos
Message 1 of 3
(2,856 Views)
Solution
Accepted by topic author OddvarC

First, to fix the exception, add niPrimitives:GraphConfiguration.UseBackgroundProcessing="False" to the XAML for your graph (xmlns:niPrimitives="http://schemas.ni.com/controls/2009/xaml/presentation/primitives").

 

To give a little more background, the disposed exception occurs because of an optimization made by the chart collection: when the graph requests access to the chart data, the chart returns a reference to the live data in the collection. This avoids a memory copy, but means that any change to the chart can invalidate the data held by the graph.

 

Also, thank you for including that small example program — this made it very easy to diagnose the issue! For future reference, you can look at the InnerException to see what actually caused the target invocation to fail.

~ Paul H
0 Kudos
Message 2 of 3
(2,830 Views)

Thanks a quick reply Paul, this seems to fix the issue!

0 Kudos
Message 3 of 3
(2,587 Views)