01-30-2020 09:45 AM
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>
Solved! Go to Solution.
01-30-2020 11:15 AM
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.
02-03-2020 08:29 AM
Thanks a quick reply Paul, this seems to fix the issue!