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.
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.
05-22-2016 03:08 AM
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].
Solved! Go to Solution.
05-23-2016 10:43 AM
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!
05-23-2016 11:21 AM
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.
06-14-2016 05:25 AM
The visual host project with the NI graph is attached.
When you click on start button you get the following exception :
06-15-2016 10:10 AM
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...
06-29-2016 06:55 AM
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.
06-30-2016 05:39 PM
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.
07-01-2016 11:23 AM
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