0

I have an application where a DAQ system samples data at about 1 kHz which is then written to a DataTable.

The code block below shows part of the code which adds data to the datatable.

    Public Sub AddTimeLoadData(DateTime As DateTime, DataPointNo As Integer, ClampForceN As Double, _
                               TransverseForceN As Double, TransverseDispMm As Double, NumLoadCycles As Integer)

        Try
            _tblTimeLoadData.AddtblTimeLoadDataRow(NumLoadCycles, TransverseDispMm, TransverseForceN, ClampForceN, DataPointNo, DateTime, _TimeLoadTestRow)
            _timRaiseDataAdded.Start()
        Catch ex As Exception
            Throw New Exception("Time/load data could not be added: " & ex.Message, ex)
        End Try
    End Sub

Updating the GUI each time AddTimeLoadData is called would be unnecessary, so instead I start a System.Timers.Timer. At the Elapsed event of the timer, I raise the TimeLoadDataUpdated event.

In the GUI another class is listening to this event, and updates the chart. This works good most of the times, but occasionally I get an IndexOutOfRangeException when reading from the data table.

It is pretty clear that this has something to do with synchronization, but I have not yet figured out exactly what might be the issue. Looking at the code, the index 'i' would not really be able to go out of range. One idea that came up is that if the for loop reaches last row at the same time as it is being created I might have a problem so I could just try updating the for loop to

For i As Integer = s.Points.Count To sender.tblTimeLoadData.Count - 2

Or maybe there is something else that I have foreseen!?

LinusN
  • 51
  • 3
  • 2
    Well - seeing as you have pinpointed the error and are in debug mode; what are the values `s.Points.Count` and `sender.tblTimeLoadData.Count` and compared to the number of Rows? – Allan S. Hansen Sep 01 '16 at 09:45
  • 1
    Duplicate of [What is IndexOutOfRangeException and how do I fix it?](http://stackoverflow.com/questions/20940979/what-is-indexoutofrangeexception-and-how-do-i-fix-it) – Bjørn-Roger Kringsjå Sep 01 '16 at 17:34
  • Strange enough, when I check in the debugger, 'I' is never greater than sender.tblTimeLoadData.Count - 1. – LinusN Sep 01 '16 at 22:42

1 Answers1

0

VB keep in memory the "To" part of the for loop.

    Dim c As Integer

    c = 3

    ' This will print 0, 1, 2, 3
    For i As Integer = 0 To c
        c = 10
        Console.WriteLine(i)
    Next

You might want to consider using a while loop instead.

    Dim c As Integer

    c = 3

    Dim i As Integer = 0

    ' Will print 0 to 9
    While i < c
        c = 10
        Console.WriteLine(i)

        i += 1
    End While

Or properly synchlock everything because even between the While/For line and the Rows(i) line, there is a chance the item will be deleted.

Also, if your timer is there to update the UI. You should look into remove all business rules out of it. Have your ds already populated with the proper data point before doing anything on the UI.

the_lotus
  • 12,668
  • 3
  • 36
  • 53
  • Rows are never deleted from the DataTable, so the FOR loop should not be an issue regarding that. I want to update the UI "live" while data is being received from the DAQ system. The only functionality in the timer event handler is copying data from the datatable to the OxyPlot chart Series. – LinusN Sep 01 '16 at 22:40
  • @LinusN tblTimeLoadData clearly has less rows that when you started the loop. Some rows were removed. Unless your .Count is somehow different that your .Rows.Count – the_lotus Sep 02 '16 at 11:24
  • Rows are not removed. That's what's confusing me. – LinusN Sep 13 '16 at 16:40