Есть класс, ещё не дописанный. Он реализует очередь принятых UDP пакетов. И резиновый буфер, возможно его следовало бы реализовать на классе набора, а не на двух массивах. Но я решил что так он будет работать быстрее в случае накопления большой очереди. Хотя в моём проекте большой очереди не будет и я страдаю от перфекционизма.
Алгоритм. Новые пакеты дописываются в конец текущего массива, при определённых условиях заполненности, содержимое текущего массива копируется будущий начиная с текущего указателя.
TextBuffers[f].Insert(TextBuffers[p].Copy(CurrentPosition))
Но вот как понять оптимальный момент в который надо начинать этот процесс, я не знаю. Если ждать слишком мало, то то тасоваться в памяти данные будут слишком часто. Если ждать слишком долго, то пустые элементы будут занимать память зря. А если ещё и очередь успеет накопиться, то перемещать её будет сравнительно долговато. Хотя в моём проекте большой очереди в принципе не будет. Но меня заинтересовал сам вопрос. Как вычислить оптимальный момент для переноса буфера в чистый массив?
' Класс для отслеживания событий UDP сокета и приёма текстовых данных из него
Public SocketUDP As New UdpSocket
Private Const CountBuffers As Integer = 2
Private Const MaxBuffers As Integer = 1 ' CountBuffers -1
Private Const WaitTime As Float = 0.02 ' Время блокирующего ожидания прихода пакета
Private TextBuffers As String[][CountBuffers]
Private CurrentBufferNumber As Integer ' Текущий буфер
Private CurrentPosition As Integer ' Текущая позиция для чтения в текущем буфере
Private CountPackets As Integer ' Количество принятых пакетов
Public ErrorToMessage As Boolean ' Если равно True, то ошибка будет в виде сообщения попадать в буфер
Public ErrorToMessageText As String ' Текст сообщения о ошибке, например "error=" и после сразу код ошибки
Public ErrorLastCode As Integer ' Код последней ошибки
Public Sub _new()
Dim a As Integer
For a = 0 To MaxBuffers
TextBuffers[a] = New String[]
Next
End
Public Function GetTextMessage(Optional TextNoMessege As String = "") As String ' Возвращает пакет из буфера
Dim r As String
If CountPackets > 0 Then
' Пакет есть в буфере
r = TextBuffers[CurrentBufferNumber][CurrentPosition]
TextBuffers[CurrentBufferNumber][CurrentPosition] = ""
If CurrentPosition < TextBuffers[CurrentBufferNumber].Max Then CurrentPosition = CurrentPosition + 1 ' Передвинуть текущую позицию при условии что она не крайняя
CountPackets = CountPackets - 1
Else
' Пакета нет в буфере
If TextNoMessege <> "" Then
r = TextNoMessege
Else
Do While CountPackets = 0
Wait WaitTime
Loop
Endif
Endif
' Нужно ли сейчас передвинуть буфер?
Return r
End
Public Function CountMessages() As Integer
Return CountPackets
End
Public Sub SwapBuffers() ' Функция меняет буферы, тем самым осовобождая память.
Dim a As Integer, m As Integer
Dim p As Integer, f As Integer ' Прошлый и будущий буферы
p = CurrentBufferNumber
f = f + 1
If f > MaxBuffers Then f = 0 ' Вычисление номера следующего буфера
m = TextBuffers[p].Max
If TextBuffers[p].Count = 0 Then TextBuffers[p].Add("") ' Если буфер совсем пустой, то добавить балластный элемент дабы в цикле не произошла ошибка
' Можно было бы поставить в условие сам цикл, но опасаюсь что это приведёт к потенциальной запутанности при усложнении
TextBuffers[f].Insert(TextBuffers[p].Copy(CurrentPosition))
'For a = CurrentPosition To m
' TextBuffers[f].Add(TextBuffers[p][a])
'Next
CurrentBufferNumber = f
TextBuffers[p].Clear ' Очистка буфера
CurrentPosition = 0
End
Public Sub SocketUDP_Read()
Dim s As String
Dim sCad As String
Read #SocketUDP, s, Lof(SocketUDP) ' Считать пакет из сокета
If Len(s) > 0 Then
TextBuffers[CurrentBufferNumber].Add(s) ' Добавить пакет в буфер
CountPackets = CountPackets + 1
End If
End
Public Sub SocketUDP_Error()
ErrorLastCode = SocketUDP.Status
If ErrorToMessage Then
TextBuffers[CurrentBufferNumber].Add(ErrorToMessageText & s) ' Добавить пакет с описанием ошибки в буфер
CountPackets = CountPackets + 1
Endif
End