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,075 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,049 Views)

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

0 Kudos
Message 3 of 3
(1,806 Views)