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 graph with visual host

Solved!
Go to solution

 

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

 

But when we added a new data to graph (in the graph's dispatcher), the appliaction crashed with InvalidOperationException: "The calling thread cannot access this object because a different thread owns it".

 

It seems that you are using with application's dispatcher instead of graph's dispatcher in your code. It's right?

 

If yes, is there a way to separate from the main application UI thread to the graph UI thread? 

 

[Our main application is very heavy and the graph suppose to handle a real time data, and when both of them on the same UI thread the UI stack and threfore we want to separate them].

0 Kudos
Message 1 of 8
(7,072 Views)

Hi hodaya273,

This seems to be more of a general C# programming question than something specific to Measurement Studio. You should be able to find plenty of suggestions for communicating between threads on other sites, and I've linked Microsoft's recommendations for this below as well as a discussion on creating multiple UI Threads. 

https://msdn.microsoft.com/en-us/library/ff649143.aspx#scag-ch06_topic4
http://stackoverflow.com/questions/5716804/can-does-wpf-have-multiple-gui-threads

Essentially you will need to update the graph in the thread it belongs to, rather than the thread you are acquiring data in. Since the graph is a UI object, it currently lives in your main UI thread and you need to create a separate UI thread for it. Hopefully this helps point you in the right direction!

Charlie J.
National Instruments
0 Kudos
Message 2 of 8
(7,051 Views)

As a quick reply, we do reference the Dispatcher in the graph, but I believe we use the dispatcher from the current thread. Did you initialize the dispatcher on the separate thread used to host the graph, and use that dispatcher to communicate with the graph?

 

Posting the exception or a code example would help narrow down the problem.

~ Paul H
0 Kudos
Message 3 of 8
(7,049 Views)

The visual host project with the NI graph is attached.

 

When you click on start button you get the following exception :

Capture.PNG

 

0 Kudos
Message 4 of 8
(6,897 Views)

Hi hodaya273,

The above post from phensen is correct, and I believe you should also be using the Dispatcher.Invoke function to interact with UI Objects on a different thread. I changed your "Data.Add(signal.Data);" call to the lines below and did not see the error any more. I don't have enough knowledge of multithreading UIs in C# to fully help you with what changes you need, nor do I know if the changes I made actually resulted in your program running properly. You should be able to find other resources online since this is not specific to Measurement Studio controls. 

System.Windows.Threading.Dispatcher.Run();
Application.Current.Dispatcher.Invoke(new System.Action(() => Data.Add(signal.Data)));

Per the following Stack Overflow page, you need to use the Invoke function when you update UI Elements from a different thread.
http://stackoverflow.com/questions/9732709/the-calling-thread-cannot-access-this-object-because-a-di...

Charlie J.
National Instruments
0 Kudos
Message 5 of 8
(6,878 Views)

The idea of Visual Host is to be abled to run some UI elements simultaneously in WPF.

 

Since we are using NI chart to display data in real time, and because there are more system components that work in parallel with the NI chart (and get stuck because of the speed of the charting) we want to separate the dispatcher of the components.

 

I.E. : NI chart will get it's own dispatcher (separately from the main dispatcher) and be able to run in parallel with other UI components without causing the system to freeze.

 

BUT

 

we have the problem that described above, it's look like the NI chart using in Application Dispatcher, and therefore we get the exception when we try to use it from the new dispatcher (where the NI chart was created).

 

the using of :

System.Windows.Threading.Dispatcher.Run();
Application.Current.Dispatcher.Invoke(new System.Action(() => Data.Add(signal.Data)));

 

dosn't help us beacuse we need to use the dispatcher where the NI chart was created.

 

0 Kudos
Message 6 of 8
(6,767 Views)

Hi hodaya273,

I understand the concern about displaying data, but my understanding of general C# threading is that the UI for a window is on the same thread with new windows being necessary for fully functional new UI threads. Generally having everything on the same UI thread should not cause any issues in updating the chart, especially when updating at a rate of 10-20 milliseconds is more than enough to appear to be "real time" to a user. In this case using the Invoke method from the thread you generate data on to update the UI thread is the more standard approach.

That being said, the HostVisual may be something you can use, I just am not sure what the exact caveats for using it are. 

From your application, the current concern is that calling a specific function causes that error. I have a couple suggestions of how you could investigate further:
You have access to both the WPF Chart Dispatcher and the Dispatcher you create for the second UI Thread. Could you try comparing those values in some way to see if we assign the chart dispatcher separately from the thread you are creating that instance on for some reason?
Have you tried performing the same operation with a different control not from Measurement Studio? That is, can you create a HostVisual for a different WPF UI element and programmatically update it? I know the Microsoft Example runs, but I haven't seen a large number of examples making use of that functionality otherwise. 

Charlie J.
National Instruments
0 Kudos
Message 7 of 8
(6,720 Views)
Solution
Accepted by topic author hodaya273

Based on the article you linked to, I created the attached test application that displays a graph using a HostVisual. I was able to communicate with the graph using its dispatcher, which was different from the one on the main UI thread.


Also, you may be interested in the techniques listed here for multi-threaded WPF controls: Create a WPF “control” that is run in an external process

~ Paul H
Message 8 of 8
(6,704 Views)