DoEvents и выполнение одновременно одной процедуры

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

DoEvents и выполнение одновременно одной процедуры

Сообщение Source » 13.09.2007 (Чт) 21:50

В Wsk_DataArrival сокета читаю данные в глобальный массив GetDat. Затем управление передаётся обработчику таймера напрямую (как обычный вызов процедуры, просто мне там удобно держать кусок кода) tmrGet_Timer, где вызывается процедура, в которой есть DoEvents. И после сего сокет принимает новый пакет UDP, который перезаписывает нужные данные (выходит ошибка из-за отсутствия нужных данных). Вопрос - почему Wsk_DataArrival вызывается повторно, когда предыдущий вызов Wsk_DataArrival не завершился и действительно ли в этом виноват DoEvents?

1а. Если бы не было ошибки, как бы происходило выполнение двух вызовов Wsk_DataArrival - параллельно и они бы нормально завершились?

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

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 13.09.2007 (Чт) 22:16

и действительно ли в этом виноват DoEvents?

Что значит "виноват"? Это первейшее свойство его вызова. Что просишь у компа, то и получаешь.

параллельно

Нет, последовательно.

или же есть такие моменты

Или же нет таких моментов.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 13.09.2007 (Чт) 23:00

Нет, последовательно.
Но ведь же произошёл 2-й вызов после DoEvents, когда первый не завершился?

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 13.09.2007 (Чт) 23:03

Произошёл, ровно тем же образом, которым происходит вызов одной процедуры из другой.

Код
Код: Выделить всё
sub foo
  foo2
end sub

sub foo2
  msgbox "!"
end sub
непоняток не вызывает?
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 13.09.2007 (Чт) 23:28

пример не вызывает. Но каким образом произошло у меня?
Private Sub Wsk_DataArrival(ByVal bytesTotal As Long)
if True then DoEvents 'Wsk_DataArrival ?
...
End Sub

После DoEvents идет другой код. Значит, при DoEvents процессор перешёл на выполнение второго Wsk_DataArrival, а потом управление перешло на код после DoEvents? А, ну да, на DoEvents управление передаётся обработчикам событий :)

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 13.09.2007 (Чт) 23:41

это натолкнуло меня на мысль, если сделать так:
Код: Выделить всё
Public CountSubWsk as long

Private Sub Wsk_DataArrival(ByVal bytesTotal As Long)
CountSubWsk=CountSubWsk+1
if CountSubWsk<1000 then DoEvents else CountSubWsk=0
'обработка пакета
End Sub

Если заносить данные в отдельный массив для каждого пакета, а потом обрабатывать, то такой способ позволит очень быстро вытягивать пакеты из буфера сокета, который, вроде не так велик. И пакеты не будут теряться из-за задержки обработки данных и переполнения буфера сокета. Хотя, м.б. такой нарастающий вызов Wsk_DataArrival может привести к переполнению стека... Но можно поставить глобальный счётчик. Но тогда будет большая задержка, когда будет обрабатываться 1000 пакетов. Но стек будет почти пуст. Здорово. Действительно ли это будет эффективнее?
Интересно, а сколько данных может принять буфер сокета?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 14.09.2007 (Пт) 8:30

Если просто нужно, чтобы был свой массив для каждого пакета, сделай его локальным внутри Wsk_DataArrival.

Размер буфера сокета зависит, как минимум, от типа интерфейса: ясно, что для гигабитной сетки он намного больше.
Изображение

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 14.09.2007 (Пт) 16:25

а как этот размер можно получить?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 14.09.2007 (Пт) 16:29

Его не нужно получать. От него не нужно зависеть.
Изображение

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 14.09.2007 (Пт) 17:13

мне интересно, каков его размер. Я буду в таймере определять процент его заполнённости и ориентироваться, теряются ли пакеты. Может, он будет у меня постоянно заполнен на 100%, тогда я должен буду принять меры!

Amed
Алфизик
Алфизик
 
Сообщения: 5346
Зарегистрирован: 09.03.2003 (Вс) 9:26

Сообщение Amed » 14.09.2007 (Пт) 17:14

Все это производится автоматически.

А какие меры, например?

Source
Постоялец
Постоялец
 
Сообщения: 351
Зарегистрирован: 04.09.2007 (Вт) 11:21

Сообщение Source » 14.09.2007 (Пт) 19:35

ну вы чё, издеваетесь? Поставлю буфер к стенке и расстреляю!


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Google-бот и гости: 85

    TopList