From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

wpf multithread graph error

Solved!
Go to solution

When I create 2 threads which respectively display 2 graphs, an error occurs.

original.png

When I comment "_controlDispatcher1.BeginInvoke(aps1[f], simulatedData)" out, no error occurs.

code in MainWindow.xaml.cs line:320

 

full code in testmultithread.zip

 

0 Kudos
Message 1 of 4
(3,893 Views)

We try to create NI WPF graph from another UI thread, as described in this link:

http://forums.ni.com/t5/Measurement-Studio-for-NET/Wpf-graph-with-visual-host/m-p/3298502

0 Kudos
Message 2 of 4
(3,892 Views)
Solution
Accepted by jiewei_li

I was able to reproduce the problem with your test project, and have create a task to fix this issue for the next release.

 

The underlying problem is with the cache we use to save point textures when rendering with bitmaps. From your application, simple workarounds like "use Vector rendering" and "don't use point renderers" did not seem appropriate. However, by using pre-initialized shared renderers, you can avoid the cache access exception and still use point rendering. Here are the changes I made to your project to get this working:

 

1) PointGraphicsReal.xaml

Remove the <ni:Graph.Plots> section, where the local point renderers are created.

 

2) PointGraphicsReal.xaml.cs

Declare a static collection of point renderers to share across all graphs, and use these as the default for the PointGraphicsReal graph:

 

    private static readonly SolidColorBrush[] _pointFills = new[]{
        Brushes.Red,
        Brushes.Lime,
        Brushes.Blue,
        Brushes.Yellow,
        Brushes.Magenta,
        Brushes.Cyan,
        Brushes.Red,
        Brushes.Lime,
        Brushes.White,
        Brushes.Lime,
        Brushes.Red,
        Brushes.Yellow,
        Brushes.Blue,
        Brushes.Cyan,
        Brushes.Magenta,
        Brushes.Lime,
        Brushes.Red,
        Brushes.White,
    };

    public static readonly PlotRendererCollection PointRenderers = new PlotRendererCollection(
        _pointFills.Select( fill => {
            var pointRenderer = new PointPlotRenderer { Shape = PointShape.Ellipse, Fill = fill, Stroke = null };
            // Freeze the renderer so that it can be used on any thread.
            pointRenderer.Freeze( );
            return pointRenderer;
        } )
    );

    public PointGraphicsReal( ) {
        InitializeComponent( );

        graph.DefaultPlotRenderers.AddRange( PointRenderers );

        // ...
    }

 

3) MainWindow.xaml.cs

Initialize the shared point renderers on the main UI thread, before they are used on any other threads, but using them in a hidden graph.

 

    public MainWindow( ) {
        new NationalInstruments.Controls.Primitives.Tables.RenderTargetBitmapWrapper( 1.0, 1.0 );
        InitializeComponent( );

        // Use all of the the shared renderers on one thread, to pre-cache the render settings for safe use on all threads.
        var graph = new Graph( );
        graph.Visibility = Visibility.Hidden;
        graph.RenderMode = RenderMode.Hardware;
        graph.DefaultPlotRenderers.AddRange( PointGraphicsReal.PointRenderers );
        graph.Data.AddRange( Enumerable.Repeat( (object)default( Point ), graph.DefaultPlotRenderers.Count ) );
        var panel = (Panel)this.Content;
        panel.Children.Add( graph );
    }

~ Paul H
0 Kudos
Message 3 of 4
(3,847 Views)

Hi all,

 

This issue is fixed in Measurement Studio 2019.

 

Cheers,

Ryan Curtis

Product Support Engineer

Automated Test Software R&D

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