Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Delay between interrupt and callback

We are using a semi-period-counter to precisely measure the intervals between the signal-edges on an inductive sensor (see code below). There are about 5 events / second so not really a high-performance task.

 

We have however the additional requirement to know when these events happened in real-world time (say UTC). To determine this, we store the computer-time every time the callback is invoked and at the end of the measurement we calculate the real-world time using regression over all the interval/timestamps pairs.

 

This works well most of the time but since we changed to .NET 4.0 we sometimes have extremely long delays (up to 800 ms!) between the actual occurrence of the events and the invocation of the callback. Errors like this make the regression-calculation unusable. Therefore my question:

 

Is it possible to determine how much time passed between the interrupt and the invocation of the callback? Or can we optimize our code to reduce those delays?

 

private void Initialize() {
    task = new Task("Task1");
    task.SynchronizeCallbacks = false;
 
    CIChannel ciChannel = task.CIChannels.CreateSemiPeriodChannel("Dev1/ctr0""Task1", 0.0001, 200.0, CISemiPeriodUnits.Seconds);
 
    ciChannel.DuplicateCountPrevention = false;
    ciChannel.SemiPeriodStartingEdge = CISemiPeriodStartingEdge.Rising;
    ciChannel.DataTransferMechanism = CIDataTransferMechanism.Interrupts;
    ciChannel.SemiPeriodDigitalFilterMinimumPulseWidth = 0.0001;
    ciChannel.SemiPeriodDigitalFilterEnable = true;
 
    task.Timing.ConfigureImplicit(SampleQuantityMode.ContinuousSamples, 100);
    task.Stream.Timeout = -1;
 
    reader = new CounterReader(task.Stream);
    reader.SynchronizeCallbacks = false;
    readerCallback = new AsyncCallback(HandleReaderCallback);
    reader.BeginReadSingleSampleDouble(readerCallback, null);
}
 
private void HandleReaderCallback(IAsyncResult ar) {
    double interval = reader.EndReadSingleSampleDouble(ar);
    long timestamp = DateTime.Now.Ticks;
    // Store interval and timestamp for later calculation
    reader.BeginReadSingleSampleDouble(readerCallback, null);
}
0 Kudos
Message 1 of 2
(4,481 Views)

Hi, 

As far as the windows threading model is concerned it does not guarantee the invocation of particular method at a specified time. Specially in .net 4 which highly utilizes the pool of threads to execute its tasks. 

The way you are invoking the callback continuously may have cause race condition in your code , therefore causing the data integrity problem which you are assuming as long delays. To resolve this you have to prevent reentrancy in your Callback method.. There is a very good help inside the MSDN for preventing reentrancy/race condition using Interlocked.CompareExchange() method. 

 

When you control the race condition .. it is possible that your delays will be shown up properly.

 

I hope that helps.

 

 

0 Kudos
Message 2 of 2
(4,474 Views)