Member 12561559 Ответов: 1

Как сделать "исходный массив был недостаточно длинным. Проверьте srcindex и длину, а также нижние границы массива."I...


Кажется, я получаю эту ошибку "иногда", чаще всего, когда останавливаю некоторые потоки и перезапускаю их или другие, на верхних потоках, которые уже запущены..
т.е.
У меня запущено 15 потоков, я останавливаю поток 12 и 14 на несколько секунд, затем перезапускаю 12 и 14, а затем ошибка "может" произойти.

Деталь....

У меня есть список T, класс со свойствами, которые я добавляю в него из нескольких запущенных потоков.
Поскольку он строит build up ThreadResults с данными, у меня есть основной тикер формы, который выполняет некоторую работу над ThreadResults в строке(0), с помощью Do Until ThreadResults.Количество=0

в конце первого цикла DO, перед командой loop, у меня есть
ThreadResults.RemoveAt(0)
который удаляет элемент из нижней части списка, .NET затем должен перетасовать список вокруг, принося элементы от 1 до 0, от 2 до 1, от 3 до 2 и т. д. И ThreadResults.Отсчет идет вниз уменьшает на один пункт, и цикл продолжает откалывать на RemoveAt(0) до тех пор, пока число равно нулю, то выход из цикла в целом, выполняет резьбу.слэп на несколько секунд и начинает цикл снова (все это время потоки добавят один пункт к списку), если это необходимо.

Иногда я не получаю никаких ошибок, в течение нескольких часов, в других случаях - чаще всего это происходит, когда я останавливаю некоторые потоки, а затем перезапускаю их, в то время как другие потоки продолжают работать в фоновом режиме, как указано выше.

У меня есть ощущение , что цикл быстрее, чем перестановка списка - даже в режиме отладки, где я могу поймать ошибку , я иду и смотрю на ThreadResults(0).FrequencyID и я получим значение, но ошибка сохраняется, в режиме отладки removeat(0) вызывает повторное появление ошибки.

Есть ли способ справиться с этим? Должен ли я вообще использовать список свойств и, возможно, переключиться на другой тип списка из-за потоковой передачи? Возможно, мне следует поставить какое-то ожидание в моих подпотоках, когда основной поток попадает в точку удаления, и чтобы он удалялся только тогда, когда я знаю, что все мои потоки приостановлены, прежде чем продолжить.

Надеюсь, это имело смысл ! :) и спасибо за любые предложения.

Я включил список с некоторыми свойствами (всего их около 10) - может быть, мне следует использовать набор данных в памяти для управления им и запрашивать его в цикле, а не список, который не кажется потокобезопасным?


<pre>Friend ThreadResults As New List(Of Thread_History_Class)()

    Public Class Thread_History_Class
      
    Private _FrequencyID As Int64 = 0
    Private _Port As Int32 = 0
    Private _ResultTxt As String = ""
    Private _Success As Boolean = False



    Friend Sub New()
' do nothing

    End Sub

    Friend Sub New(ByVal FrequencyID As Int64,
                   ByVal Port As Int32,
                   ByVal ResultTxt As String,
                   ByVal Success As Boolean)
                  
  Friend Property Success() As Boolean
        Get
            Return _Success
        End Get
        Set(value As Boolean)
            _Success = value
        End Set
    End Property


        Friend Property ResultTxt() As String
        Get
            Return _ResultTxt
        End Get
        Set(value As String)
            _ResultTxt = value
        End Set
    End Property

    Friend Property Port() As Int32
        Get
            Return _Port
        End Get
        Set(value As Int32)
            _Port = value
        End Set
    End Property



    Friend Property FrequencyID() As Int64
        Get
            Return _FrequencyID
        End Get
        Set(value As Int64)
            _FrequencyID = value
        End Set
    End Property

End Class


Что я уже пробовал:

Возможно, мне следует использовать набор данных в памяти, а не список, или заставить мои потоки ждать, пока RemoveAt(0) не будет завершен-я просто собирался использовать thread.sleep, но, возможно, есть лучший способ управления списком в условиях потока?

Richard MacCutchan

Вам нужно синхронизировать свои потоки так, чтобы только один поток мог изменить порядок/размер массива в любое время.

Member 12561559

Ура Ричарду, я думал, что это будет так, хотя у Фила, кажется, есть потокобезопасный метод ниже, я погуглил его, кажется, он не очень часто используется, возможно, большинство людей не используют потоки и списки, но я посмотрю на его решение, и если я не могу получить этот метод вокруг своей головы, я пойду на ожидание (хотя я бы предпочел не делать этого, так как тайминги важны для этих потоков) - но, по крайней мере, есть пара вещей, на которые я могу посмотреть. Ура и хороших выходных :)

1 Ответов

Рейтинг:
11

phil.o

Может быть, вам было бы интересно использовать потокобезопасный список вместо этого, чтобы избежать попадания в это случайное состояние гонки?
Потокобезопасные Коллекции | Microsoft Docs[^]


Member 12561559

Спасибо Фил - я посмотрю на это, никогда раньше не слышал об этих коллекциях, надеюсь, я смогу заставить их работать с тем, что у меня есть - будет лучше, чем состояние ожидания на потоках из - за того, что тайминги важны в том, чего я пытаюсь достичь-спасибо и хорошего уик-энда !

phil.o

И ты тоже! Пожалуйста.