Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Are there any issues with the way I am managing the lifetime of my Task?

Hey all,

 

I have recently become very skeptical of the way I am using managing the lifetime and state of a DAQmx Task object. The Task object under discussion is responsible for doing finite analog output. The application allows the user to set a variety of parameters that influence what the waveform being output looks like. Every time the user changes a parameter, the system regenerates what it will send out of analog output channel zero. Once this regeneration is complete, the AnalogOutput class below will receive a message that contains the generated samples. Every time that the AnalogOutput class receives an updated sequence of samples to output, it re-configures the hardware via the Configure() method.

 

public class AnalogOutput : IAnalogOutput, IHandle<SamplesAvailableEvent>
{
    private Task _task;
    private AnalogSingleChannelWriter _writer;
    private double[] _deliverySamples;
    private readonly IDeviceLocator _deviceLocator;
    private readonly IEventAggregator _eventAggregator;
    private int _numberOfSamplesToOutput;

public AnalogOutput(IEventAggregator eventAggregator, IDeviceLocator deviceLocator)
    {
        _eventAggregator = eventAggregator;
    _deviceLocator = deviceLocator;
        _numberOfSamplesToOutput = 2;
        _eventAggregator.Subscribe(this);
        Configure();
    }

public void Configure()
        {
            if (_task != null)
            {
                _task.Dispose();
                _task = null;
            }

            _task = new Task("AnalogOutputTask");
            _task.AOChannels.CreateVoltageChannel(_deviceLocator.DeviceName + "/ao0", "ao0", -10, 10, AOVoltageUnits.Volts);
            _task.Timing.ConfigureSampleClock("", SamplingInfo.OutputSampleRate, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, _numberOfSamplesToOutput);
            _task.Done += (sender, args) =>
            {
                _eventAggregator.PublishOnUIThread(new DeliveryCompleteEvent());
            };
            _task.Control(TaskAction.Verify);
            _writer = new AnalogSingleChannelWriter(_task.Stream);
        }

public void Start()
        {
            _writer.WriteMultiSample(false, _deliverySamples);
            _task.Start();
        }

public void Stop()
        {
            if (_task == null)
            {
                return;
            }

            _task.Stop();
            _task.Control(TaskAction.Unreserve);
        }
public void Handle(SamplesAvailableEvent message)
        {
            _numberOfSamplesToOutput = message.Samples.Count + 1;
            _deliverySamples = new double[_numberOfSamplesToOutput];;
            message.Samples.ToArray().CopyTo(_deliverySamples, 0);

            // Update finite sample clock since it is possible that the number of samples
            // to output has changed.
            Configure();
        } }

The statement below may be unclear to some folks, it is from Caliburn.Micro the MVVM framework my app is using. This statement publishes a message of type DeliveryCompleteEvent. Once this is published, the Handle(DeliveryCompleteEvent message) method will be executed. This method is shown a little below.

_eventAggregator.PublishOnUIThread(new DeliveryCompleteEvent());

To help give a more complete picture of what is happening in the application, more code is provided below. These functions are found within my applications view model and interact with the AnalogOutput class pictured above.

public void Deliver()
{
    _analogOutput.Start();
}

public void Handle(DeliveryCompleteEvent message) { _analogOutput.Stop(); _analogOutput.Configure(); }

With that being said I am left with the following questions...

  • I am disposing of the task before I reconfigure it. I have seen comments in these forums that lead me to believe I should re-use the task instead of recreating it. Should I be managing the lifetime of this task differently?
  • Is there any cleanup I should be doing on the AnalogSingleChannelWriter object?

Any comments on the code above or answers to these questions are welcome, thanks!

0 Kudos
Message 1 of 3
(2,431 Views)

Hello,

 

For the first inquiry of disposing a task: when we code in LabVIEW it's more efficient and faster to keep the same task and then just update the information is a while loop of sorts, similar can be said with Visual Studio or LabWindows/CVI. It isn't technically necessary, but it's just best practice to do so.

 

For the second inquiry, I would suggest looking at Text Based NI-DAQmx Data Acquisition Examples to see if it is something that you personally need to clean up.

 

Parul M. 

Applications Engineer

National Instruments

0 Kudos
Message 2 of 3
(2,387 Views)

Thanks for the information Parul. I will look into improving my code by updating the existing task instead of destroying it and creating a new one. I will check out the provided link as well.

0 Kudos
Message 3 of 3
(2,383 Views)