12-02-2005 02:29 PM
12-02-2005 03:08 PM
The Measurement Studio hardware class libraries use delegates to notify you when an acquisition is complete. The hardware class libraries (NI4882, VisaNS, and DAQmx) all use the same pattern for asynchronous I/O (i.e. I/O in a thread other than the thread that initiated it). For each Read or Write method that initiates an acquistion or generation, there exists a corresponding pair of BeginRead/EndRead or BeginWrite/EndWrite methods that take a delegate, create a thread to do the acquisition, and call your delegate when the acquisition or generation is complete.
Assuming you are using the DAQmx class library, check out the following example and search for BeginReadMultiSample to see how this is done:
C:\Program Files\National Instruments\MeasurementStudioVS2003\DotNET\Examples\DAQmx\Analog In\Measure Voltage\ContAcqVoltageSamples_IntClk\Vb
This pattern is described in concept topics for the hardware class libraries. The DAQmx concept topic is Asynchronously Reading and Writing with the NI-DAQmx .NET Class Library. There are similar topics for the NI4882 and VisaNS class libraries, if you are using those.
12-02-2005 05:02 PM
12-06-2005 10:26 AM - edited 12-06-2005 10:26 AM
@serpos wrote:
"...BeginWrite/EndWrite methods that take a delegate, create a thread to do the acquisition, and call your delegate when the acquisition or generation is complete."
i am looking at the ContAcqVoltageSamples_IntClk example.
so the delegates are there...just hidden in the DAQmx?
the supplied examples have the "callback".
seems to resemble a delegate address..
I wouldn't describe the delegates as being hidden in the DAQmx driver. To initiate an asynchronous acquisition, you create a delegate of type AsyncCallback that references a method that you want the driver to call when the read is complete. You then pass this delegate to the BeginRead method to start the acquisition. In the ContAcqVoltageSamples_IntClk example, the code that creates the delegate is the following:
analogCallback =
New AsyncCallback(AddressOf AnalogInCallback) If you look up AsyncCallback in the NI Measurement Studio Help, you see it is defined as follows:[Visual Basic] <Serializable> Public Delegate Sub AsyncCallback( _ ByVal ar As IAsyncResult _ )
The AsyncCallback that you create is the delegate.
Message Edited by drohacek on 12-06-2005 10:28 AM
12-06-2005 10:27 AM - edited 12-06-2005 10:27 AM
Because of the maximum limit of 5000 characters per post, I need to break up my response to your questions. This post is part 2 of 2.
@serpos wrote:
If the "AnalogInCallback" is executing, how is the stop button on the user interface acknowledged?
The callback is a spawned thread?
When you call a BeginRead method, the DAQmx driver uses a worker thread (i.e. not the thread that calls the BeginRead method) to perform the acquisition. If the thread that calls BeginRead returns to the application main message processing loop, then it is able to acknowledge the stop button on the UI, provided it isn't performing some other operation, while the acquisition is ongoing.
However, things get a little bit more complicated with respect to what happens while AnalogInCallback is executing. By default, the DAQmx driver executes AnalogInCallback in the worker thread. But this is not what is happening in the ContAcqVoltageSamples_IntClk example program. In this example program, the application instructs the DAQmx driver to execute the AnalogInCallback in the user interface thread, with the following line of code:
analogInReader.SynchronizingObject =
Me Because the driver executes AnalogInCallback in the user interface thread, the user interface thread is not processing messages and so cannot acknowledge the stop button until it finishes executing AnalogInCallback. The reason that we need to execute AnalogInCallback in the user interface thread is that AnalogInCallback updates the user interface and it is a requirement of Windows Forms controls that they be updated only from the thread that creates them. Updating the controls from another thread results in undefined behavior in the .NET Framework 1.1 and in an exception in the .NET Framework 2.0.If you need to make sure that the stop button remains responsive and you need to update your user inteface with data obtained in the AnalogInCallback, you will have to write some additional code. You have a few options:
Which of these options is best for you depends on the nature of your application. Some of the factors you might need to consider are exactly how responsive the stop button must be, how much you need to do within AnalogInCallback (e.g. does your AnalogInCallback perform expensive analysis operations on the data?), and whether your acquisition is continuous (in this case, you must make sure that you call BeginRead frequently enough to prevent the buffer on the DAQ device from overflowing).
I realize that there is a lot of information here. Please post any followup questions you might have.
Message Edited by drohacek on 12-06-2005 10:27 AM
Message Edited by drohacek on 12-06-2005 10:28 AM
12-12-2005 12:04 PM
12-12-2005 12:05 PM
12-12-2005 05:08 PM
@serpos wrote:
Can you post a simple example of your option 3?
It would be great to see how to implement ContAcqVoltageSamples_IntClk using a "worker thread" rather than having the acquisition
crammed into the UI.
Your previous posts were enlightening.
Thanks.
12-23-2005 11:33 AM
12-28-2005 04:41 PM - edited 12-28-2005 04:41 PM
Hi Philip,
Could you clarify what you mean by prioritizing the worker thread? It sounds like you are looking for a way to make sure that the DAQmx driver, which creates the read thread, will give the read thread a high priority, thus ensuring quick data delivery. I believe that the DAQmx driver already does this automatically. So the only factor affecting performance would be the usage of the CPU by other threads and processes. You could probably improve the worker thread execution speed by decreasing the CPU usage of the UI thread. As David said, a simple way to do that would be to increase the timer delay on the example he provided. Another idea might be to use a faster data display control than a DataGrid, or no UI at all.
I hope this answers your question.
Message Edited by Hexar on 12-28-2005 04:42 PM