Автор Тема: Режим OnEvent и приоритетность  (Прочитано 3385 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн VadimKHL [?]

  • Новичок
  • *
  • Сообщений: 48
  • Репутация: 0
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Режим OnEvent и приоритетность
« Создано: Декабрь 24, 2016, 17:41:09 »
Всем привет!
Нужна помощь новичку.
Ситуация такая. Есть обработка кнопок в режиме OnEvent.
При их нажатии происходит передача данных в Com порт и принятие ответного сообщения от устройства.
Так же, в бесконечном цикле While каждые 100 мс происходит обмен данных через ком порт.

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

Каким способом можно решить данную проблему?

Всем спасибо!

Русское сообщество AutoIt

Режим OnEvent и приоритетность
« Отправлен: Декабрь 24, 2016, 17:41:09 »

Оффлайн ra4o [?]

  • Продвинутый
  • ***
  • Сообщений: 484
  • Репутация: 71
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #1, Отправлен: Декабрь 27, 2016, 00:48:08 »
Возможно во время обмена данными с СОМ портом отключать режим OnEvent , после окончания - включать. Таким образом во время обмена данными скрипт не будет реагировать на нажатие кнопки.  Или , как вариант на нажатие кнопки привязать просто установку какого-нибудь флага нажатия кнопки и обработку флага по кнопке производить вне цикла работы с СОМ портом.

Оффлайн VadimKHL [?]

  • Новичок
  • *
  • Сообщений: 48

  • Автор темы
  • Репутация: 0
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #2, Отправлен: Январь 11, 2017, 09:56:54 »
Возможно во время обмена данными с СОМ портом отключать режим OnEvent , после окончания - включать. Таким образом во время обмена данными скрипт не будет реагировать на нажатие кнопки.  Или , как вариант на нажатие кнопки привязать просто установку какого-нибудь флага нажатия кнопки и обработку флага по кнопке производить вне цикла работы с СОМ портом.

Возможно. Но тогда смысл режима OnEvent вообще теряется.

А возможно ли в режиме OnEvent запустить таймер, который допустим каждые 100 мс генерирует событие, и выполняет функцию, блокируя выполнение других событий?
Т.е. как будто обычная кнопка в режиме OnEvent, которая нажимается каждые 100 мс автоматически, а не пользователем?



Оффлайн ra4o [?]

  • Продвинутый
  • ***
  • Сообщений: 484
  • Репутация: 71
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #3, Отправлен: Январь 11, 2017, 11:58:19 »
Цитировать
каждые 100 мс генерирует событие, и выполняет функцию
Код: AutoIt [Выделить]
AdlibRegister("_MyFunc", 100)

Но это Вас не спасёт от не вовремя нажатых кнопок в режиме OnEvent.
Цитировать
Возможно. Но тогда смысл режима OnEvent вообще теряется.
Если объём информации не большой, а судя по тому. что Вы читаете/пишите в СОМ порт каждые 100 мс оно так и есть. то отключение режима OnEvent на время работы с СОМ портом Вы и не заметите. Ведь у Вас задача
Цитировать
блокируя выполнение других событий?
- не принимать никаких прерываний при обмене данными, тогда и решение :
Цитировать
во время обмена данными с СОМ портом отключать режим OnEvent
« Последнее редактирование: Январь 11, 2017, 12:05:46 от ra4o »

Русское сообщество AutoIt

Re: Режим OnEvent и приоритетность
« Ответ #3 Отправлен: Январь 11, 2017, 11:58:19 »

Оффлайн VadimKHL [?]

  • Новичок
  • *
  • Сообщений: 48

  • Автор темы
  • Репутация: 0
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #4, Отправлен: Январь 12, 2017, 15:51:15 »
тогда и решение :
Цитировать
во время обмена данными с СОМ портом отключать режим OnEvent

Я думаю это не верное решение. Ситуация такая,
отключаем OnEvent, происходит обмен данными по COM, а в это время пользователь кликает по кнопке.
Ведь после включения OnEvent кнопка не будет отработана?
В итоге безответный клик по кнопке?

Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3274
  • Репутация: 856
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #5, Отправлен: Январь 12, 2017, 16:21:34 »
VadimKHL
Выставляйте флаги (разрешения) либо в цикле, либо в функциях-обработчиках. И проверяйте их, соответственно, либо в функциях, либо в цикле.
« Последнее редактирование: Январь 12, 2017, 16:28:08 от InnI »

Оффлайн VadimKHL [?]

  • Новичок
  • *
  • Сообщений: 48

  • Автор темы
  • Репутация: 0
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #6, Отправлен: Январь 13, 2017, 10:43:16 »
VadimKHL
Выставляйте флаги (разрешения) либо в цикле, либо в функциях-обработчиках. И проверяйте их, соответственно, либо в функциях, либо в цикле.

Т.е. при нажатии кнопок, вызывать функции, которые просто поднимают флаги (биты) в переменной, а в цикле While, после обмена данными с COM,
обрабатывать нажатые кнопки?

А в чем тогда будет разница данного решения по сравнению с использованием режима MessegeLoop?

Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3274
  • Репутация: 856
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #7, Отправлен: Январь 13, 2017, 13:01:06 »
VadimKHL
Цитировать
разница данного решения по сравнению с использованием режима MessegeLoop
Принципиальной разницы нет. Вопрос только в скорости реакции интерфейса. Как написано в справке по MessageLoop "вы должны убедиться, что вызываете функцию довольно часто (более 20-ти раз в секунду), иначе ваш GUI не будет откликаться на взаимодействие с элементами управления". А если вы в цикл обмена данными включите GUIGetMsg(), то всё равно придётся запоминать нажатые кнопки и обрабатывать их при выходе из цикла.
« Последнее редактирование: Январь 13, 2017, 13:14:47 от InnI »

Русское сообщество AutoIt

Re: Режим OnEvent и приоритетность
« Ответ #7 Отправлен: Январь 13, 2017, 13:01:06 »

Оффлайн ra4o [?]

  • Продвинутый
  • ***
  • Сообщений: 484
  • Репутация: 71
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #8, Отправлен: Январь 13, 2017, 14:39:33 »
Ведь даже , если устанавливать флаг нажатия кнопки скрипту нужно будет выйти из цикла работы с СОМ портом, установить флаг и вернуться обратно.  Если все-же необходимо не прерывать обработку данных с СОМ порта и работать одновременно с интерфейсом , тогда работу с СОМ портом можно вынести в отдельный скрипт (dll итп) и при необходимости из основного скрипта вызывать скрипт обработки данных.

Оффлайн VadimKHL [?]

  • Новичок
  • *
  • Сообщений: 48

  • Автор темы
  • Репутация: 0
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #9, Отправлен: Январь 13, 2017, 16:00:48 »
Ведь даже , если устанавливать флаг нажатия кнопки скрипту нужно будет выйти из цикла работы с СОМ портом, установить флаг и вернуться обратно. 

Похоже вопрос не верно описал.

Функцию работы с COM портом, которая выполняется каждые 100 мс прерывать можно сколько угодно, хоть на 10 секунд.
Нельзя нарушать условие ЗАПРОС (сообщение от ПК) - ОТВЕТ (ПК принимает).

Конкретно как происходит крах:
Функция, которая выполняется каждые 100 мс посылает запрос, и ожидает ответ.
В это время пользователь нажал кнопку, сразу посылается НОВЫЙ ЗАПРОС,  а на предыдущий запрос ответ еще не пришел.
Функция нажатия кнопки в итоге получает ответ, но не на свой запрос, а от предыдущего запроса.

Вот где проблема.

 


Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3274
  • Репутация: 856
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #10, Отправлен: Январь 13, 2017, 16:17:05 »
VadimKHL
Цитировать
посылает запрос, и ожидает ответ
И сколько времени это занимает?

Оффлайн VadimKHL [?]

  • Новичок
  • *
  • Сообщений: 48

  • Автор темы
  • Репутация: 0
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #11, Отправлен: Январь 13, 2017, 16:23:10 »
Все зависит от загруженности МК. Ответ может придти в интервале от 1 мс до 200 мс.

Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3274
  • Репутация: 856
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #12, Отправлен: Январь 13, 2017, 16:30:21 »
VadimKHL
Цитировать
до 200 мс
Для MessageLoop многовато... но попробовать можно. Тут зависит от того, как часто кнопки нажимаются и как быстро нужна реакция на нажатие.
В противном случае придётся делать гибрид - либо с флагами, либо с вкл/выкл режима.

Оффлайн VadimKHL [?]

  • Новичок
  • *
  • Сообщений: 48

  • Автор темы
  • Репутация: 0
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #13, Отправлен: Январь 13, 2017, 16:37:57 »
Накидал тестовую прогу.
OnEvent очень интересно работает.
он все события нажатия кнопок ставит в очередь. И это дает 100 процентов выполнения всех операций с GUI.
Для меня это самый правильный вариант.

Но как сгенерить события OnEvent программно, а не нажатием кнопки, что бы каждые 100 мс добавлялась в очередь еще одна функция?

Код: AutoIt [Выделить]
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>

Opt("GUIOnEventMode", 1) ; Включить режим отслеживания событий GUI.

; ====================================================================================================================
; Создаем визуальное окно и объекты в нем.
; ====================================================================================================================

; Создать визуальное окно.
$WINGUI = GUICreate("TEST", 470, 245, -1, -1, BitOr($WS_POPUP, $WS_BORDER))

; Информауионные строки.
$lbTMR1 = GUICtrlCreateLabel("TMR1:", 10, 10, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR2 = GUICtrlCreateLabel("TMR2:", 10, 25, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$lbTMR3 = GUICtrlCreateLabel("TMR3:", 10, 40, 40, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)

$idTMR1 = GUICtrlCreateLabel("0", 55, 10, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR2 = GUICtrlCreateLabel("0", 55, 25, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)
$idTMR3 = GUICtrlCreateLabel("0", 55, 40, 65, 15, $SS_LEFTNOWORDWRAP, $GUI_WS_EX_PARENTDRAG)

; Кнопки.
GUICtrlCreateButton("TMR1", 260, 70, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR1")
GUICtrlCreateButton("TMR2", 260, 95, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR2")
GUICtrlCreateButton("TMR3", 260, 120, 100, 25)
GUICtrlSetOnEvent(-1, "_TMR3")

; Системные события.
GUISetOnEvent($GUI_EVENT_CLOSE, "_CLOSEEvent")

GUISetState(@SW_SHOW, $WINGUI)

While 1
   Sleep(100)
WEnd


Func _TMR1()
   For $TMR1 = 1 To 10
      GUICtrlSetData ($idTMR1, $TMR1)
      sleep (500)
   Next
EndFunc

Func _TMR2()
   For $TMR2 = 1 To 10
      GUICtrlSetData ($idTMR2, $TMR2)
      sleep (500)
   Next
EndFunc

Func _TMR3()
   For $TMR3 = 1 To 10
      GUICtrlSetData ($idTMR3, $TMR3)
      sleep (500)
   Next
EndFunc


; ====================================================================================================================
; Функции системных событий.
; ====================================================================================================================
Func _CLOSEEvent()
    Exit
EndFunc


Оффлайн InnI [?]

  • AutoIt Гуру
  • *****
  • Сообщений: 3274
  • Репутация: 856
    • Награды
  • Версия AutoIt: 3.3.14.0
Re: Режим OnEvent и приоритетность
« Ответ #14, Отправлен: Январь 13, 2017, 17:04:35 »
VadimKHL
Цитировать
сгенерить события OnEvent программно, а не нажатием кнопки
Нужно просто программно нажать кнопку ;)
Код: AutoIt [Выделить]
AdlibRegister("BtnClick", 100)

Func BtnClick()
  GUICtrlSendMsg($idBtn, 0xF5, 0, 0) ; $BM_CLICK
;~   ControlClick($WINGUI, "", "TMR1") ; или так
EndFunc



Добавлено: Январь 13, 2017, 19:32:38
VadimKHL  [?]
Цитировать
OnEvent очень интересно работает.
он все события нажатия кнопок ставит в очередь
На самом деле очередь получается из-за того, что очередное событие не может прервать функцию, вызванную другим событием.

В режиме MessageLoop события тоже встают в очередь. Просто эта очередь "забивается" событиями движения курсора мыши. А функция GuiGetMsg() за один вызов читает одно событие. Вот и получается, что если её вызывать редко, то интерфейс "тормозит".

Вот вариант вашей "тестовой проги" в режиме MessageLoop (все события $GUI_EVENT_MOUSEMOVE вычищаются и интерфейс не тормозит)
(нажмите для показа/скрытия)
« Последнее редактирование: Январь 13, 2017, 19:32:38 от InnI, Причина: Объединение сообщений »

Русское сообщество AutoIt

Re: Режим OnEvent и приоритетность
« Ответ #14 Отправлен: Январь 13, 2017, 17:04:35 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
10 Ответов
5551 Просмотров
Последний ответ Ноябрь 12, 2011, 21:31:24
от AZJIO
5 Ответов
5045 Просмотров
Последний ответ Август 16, 2010, 20:53:06
от XpycT
3 Ответов
2581 Просмотров
Последний ответ Сентябрь 18, 2011, 15:25:23
от CreatoR
2 Ответов
2557 Просмотров
Последний ответ Сентябрь 18, 2011, 17:30:35
от Vovsla
6 Ответов
2461 Просмотров
Последний ответ Январь 19, 2012, 17:10:09
от DarWiM
5 Ответов
2720 Просмотров
Последний ответ Февраль 06, 2012, 21:03:05
от DarWiM
6 Ответов
3476 Просмотров
Последний ответ Февраль 27, 2012, 23:49:31
от Robocop
2 Ответов
798 Просмотров
Последний ответ Март 08, 2015, 21:27:50
от CreatoR
4 Ответов
1373 Просмотров
Последний ответ Сентябрь 07, 2015, 22:36:03
от Skif_off
0 Ответов
3251 Просмотров
Последний ответ Февраль 27, 2016, 15:16:47
от inververs