Doevents

TiOS - однопоточная система. Все события выполняются виртуальной машиной (VM) одно за другим, в порядке поступления в очередь событий.

Но что, если из обработчика одного из событий никогда не выходить или выйти с большой задержкой? Все остальные события будут ждать в очереди необработанными, а это может стать проблемой!

К счастью, есть оператор doevents. Поместите его в код, и когда VM дойдёт до doevents, выполнение текущей цепочки обработчика события будет приостановлено.

После этого VM выполнит все события, ожидающие в очереди, а затем возобновит выполнение исходной цепочки обработчика.

Если во время выполнения doevents в очередь добавляются новые события, в том же «раунде» doevents они обработаны не будут.

Итак, doevents позволяет процедуре дать выполниться другим событиям, пока она занята чем-то длительным:

sub on_sys_init 'calculate the sum total of all array elements -- this will surely take time!
   dim f as word
   sum = 0
   for f = 0 to 49999
      sum = sum + arr(f)
      doevents 'don't stall other events while we are going through the entire array
   next f
end sub
Блок-схема, иллюстрирующая обработку оператора doevents.

Вложенные doevents

Допустим, оператор doevents находится в цепочке on_sys_init.

Выполнение доходит до него и начинает обрабатывать другие события из очереди. Одно из них - ON_SOCK_DATA_ARRIVAL, и в цепочке обработчика этого события есть второй doevents.

Что произойдёт? Начнётся вторичный, независимый «раунд» doevents!

Когда вторичный doevents закончит выполнение, управление вернётся к первому doevents, а от него - к исходной цепочке обработчика.

Блок-схема, иллюстрирующая обработку вложенных операторов doevents.

Doevents для событий одного типа

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

Для других событий допускается постановка в очередь нескольких экземпляров.

Например, событий ON_SOCK_DATA_ARRIVAL может быть несколько - потенциально по одному на каждый активный сокет.

Предположим, что в цепочке вызовов on_sock_data_arrival есть оператор doevents. Выполнение доходит до него, обработчик события приостанавливается, и VM начинает выполнять другие события из очереди.

Одно из ожидающих в очереди событий - другое событие ON_SOCK_DATA_ARRIVAL. Что должна делать VM?

Начать его выполнение она не может: исходное событие ON_SOCK_DATA_ARRIVAL уже приостановлено, так что это было бы равносильно реентерабельному выполнению, а оно недопустимо!

Поэтому VM просто пропустит это второе событие ON_SOCK_DATA_ARRIVAL и выполнит всё остальное, что может выполнить.

Необработанное событие ON_SOCK_DATA_ARRIVAL №2 останется в очереди, пока не завершится текущее ON_SOCK_DATA_ARRIVAL. Затем оно будет обработано обычным порядком.

Блок-схема, иллюстрирующая обработку нескольких операторов doevents для событий одного типа.
Исходный материал Tibbo обновлён 12 сентября 2022Оригинал на docs.tibbo.com · Сообщить об ошибке