2016-09-01 4 views
0

У меня есть приложение, в котором система DAQ сэмплирует данные с частотой около 1 кГц, которая затем записывается в DataTable.IndexOutOfRangeException on 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 

Обновление графического интерфейса пользователя каждый раз, когда AddTimeLoadData называется будет излишним, так что вместо этого я начинаю System.Timers.Timer. В событии Elapsed таймера я поднимаю событие TimeLoadDataUpdated.

В GUI другой класс слушает это событие и обновляет диаграмму. Это работает хорошо в большинстве случаев, но иногда я получаю исключение IndexOutOfRangeException при чтении из таблицы данных.

Это довольно ясно, что это что-то делать с синхронизацией, но я до сих пор не понял, что именно может быть проблемой. Глядя на код, индекс «i» не сможет выйти из диапазона. Одна мысль, что пришла в том, что если цикл достигает последней строки в то же время, как она создается, я мог бы проблему, так что я мог бы просто попробовать обновив цикл для

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

Или, может быть, есть что-то еще, что я предвидел !?

+2

Хорошо, поскольку вы указали ошибку и находитесь в режиме отладки; каковы значения 's.Points.Count' и' sender.tblTimeLoadData.Count' и сравниваются с количеством строк? –

+1

Дубликат [Что такое IndexOutOfRangeException и как его исправить?] (Http://stackoverflow.com/questions/20940979/what-is-indexoutofrangeexception-and-how-do-i-fix-it) –

+0

Странно, когда я проверяю отладчик, «я» никогда не бывает больше, чем sender.tblTimeLoadData.Count - 1. – LinusN

ответ

0

VB хранит в памяти «To» часть цикла for.

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 

Возможно, вы захотите использовать вместо этого цикл while.

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 

Или правильно synchlock все потому, что даже между Хотя/Для линии и строк (я) линия, есть шанс, что деталь будет удалена.

Кроме того, если ваш таймер предназначен для обновления пользовательского интерфейса. Вы должны изучить все бизнес-правила. Пусть ваши ds уже заполнены нужной точкой данных, прежде чем что-либо делать с пользовательским интерфейсом.

+0

Строки никогда не удаляются из DataTable, поэтому цикл FOR не должен быть проблемой. Я хочу обновить пользовательский интерфейс «вживую», пока данные поступают из системы DAQ. Единственная функциональность в обработчике событий таймера - это копирование данных из таблицы данных в линейку карт OxyPlot. – LinusN

+0

@LinusN tblTimeLoadData явно имеет меньше строк, которые при запуске цикла. Некоторые строки были удалены. Если ваш .Count как-то отличается от того, что ваши .Rows.Count –

+0

Строки не удаляются. Вот что меня смущает. – LinusN