Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Why can I update the user interface in a callback from DAQmX?

I have been playing around with the DAQmx examples in Measurement Studio (C#) to set me up for designing a multi-threaded application to acquire data whilst processing, displaying and logging to file. This is the first time that I have used threads but I am happy that I now understand the asynchronous operations using e.g. 'BeginReadInt16()' with a callback function for when data has been acquired.
 
What I don't understand, having read the Microsoft help on asynchronous operations and threads, is how come I can update the user interface from within the callback of the DAQmx read function? I was under the impression that the user interface was on a separate thread and this could not be done. I have since written a piece of test code to asynchronously read from a serial port (using the .NET 'SerialPort' class 'BaseStream' property) and I get an error when I try and update the user interface from my callback there.
 
Could anyone enlighten me as to what I'm missing here? I like to understand these things so they don't trip me up in future.
 
Thanks.
0 Kudos
Message 1 of 5
(3,942 Views)
I appear to have stumbled across the answer to this one myself. It appears that Measurement Studio classes are using the .NET SynchronizationContext class which will ensure that any asynchronous operations started from the UI thread will execute their callbacks on the UI thread. For more information see the Measurement Studio help subject ‘Events, Callbacks, and Thread Safety in Measurement Studio .NET Class Libraries’ and the .NET SynchronizationContext class help.
0 Kudos
Message 2 of 5
(3,919 Views)

Hello CAS,

 

I would think that the DAQmx read function is architectured in a way that it will just send data to the user interface once it has enough or that the user interface is requesting the data to display when it needs to. With the callback this would be possible using event-based architecture.

 

In regards to your error though, could you give me a little bit more information on what exactly you are seeing? It might be that as you are expecting to trigger the reading of your data after the acquisition is over, your code is completely missing the trigger itself. If you want to be able to start the reading of the data in such a way, you might actually have to explicitly start this task before the end of the acquisition. This is because the call to BeginRead* function starts a new thread to retrieve the data asynchronously, and because of this there is a race condition between the two tasks as to which one will be started first--the operating system can schedule threads in any order. So, if you can start the read task and then just call it, you might be able to acheive what you set out to initially.

 

I hope this helps in a way,

Please do let me know how you get on,

 

Kind Regards,

Michael S.
Applications Engineer
NI UK & Ireland

0 Kudos
Message 3 of 5
(3,918 Views)

CAS!

It seems we pretty much replied at the same time!

I am glad you found this information, and I was going to mention in my reply how this would go in a single thread but forgot!

 

In any case, still let me know if there is anything else I might be able to help with.

 

Kind Regards,

Michael S.
Applications Engineer
NI UK & Ireland

0 Kudos
Message 4 of 5
(3,917 Views)

Hi Michael

 

Thanks for your reply. I am all sorted now. I understood why the callback from my serial reader threw an error when trying to update the UI - this is because my callback was operating on the thread performing my read serial operation rather than on the UI thread itself. I also know how to get around that with a couple of extra lines of code.

 

What I couldn't understand was how the DAQmx callback got around this so neatly but now I know that it's because it's using the SynchronizationContext class to post the callback to occur back on the original thread on which the UI is running. I think that, with a bit more research, I could work out how to use this myself and implement it in my asynchronous serial reader.

 

They're pretty involved these threads aren't they?!

 

Thanks again.

CAS

0 Kudos
Message 5 of 5
(3,911 Views)