Вверх ↑
Этот топик читают: Гость
Разработчик
Ответов: 26115
Рейтинг: 2126
#1: 2012-04-03 17:00:13 ЛС | профиль | цитата
Все вы знаете ситуацию, когда контейнер невозможно удалить из своего события и для этого ставиться таймер с маленкой задержкой. Происходит это по причине того, что удаление происходит из своего же незаконченного метода, а таймер разделяет очереди обработчика, тк его событие происходит уже в другой очереди, когда все предыдущие события уже закончены. Но создание большого количества таймеров в системе не очень хорошая идея. Для этих целей и был разработан компонент OtherQueueEvent (заменено на DeferredEvent (отложенное событие)), который позволяет выдавать событие из другой, специально созданной на момент обработки события, очереди сообщений системы, что освобождает от применения большого количества таймеров для целей разделения событий по времени

Везде, где вы раньше применяли таймера для выдачи событий из другой очереди применяйте компонент OtherQueueEvent (заменено на DeferredEvent (отложенное событие)) вместо таймера. Кроме того, элемент позволяет транслировать через себя данные

Компонент вы можете найти на SVN. При установке будет проситься во вкладку Controls (переведено во вкладку System)

Внимание! Имя компонента заменено на DeferredEvent (отложенное событие)

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



Add(MainForm,6208649,196,189)
{
Width=262
Height=228
Position=1
}
Add(Button,4244657,196,238)
{
Left=10
Top=40
TabOrder=-1
link(onClick,9260267:##add,[])
}
Add(Button,9979880,196,273)
{
Left=10
Top=65
TabOrder=-1
link(onClick,9260267:doDelete,[(254,279)(254,251)])
}
Add(MultiElementEx,13664646,280,378)
{
link(onResult,14628342:doValue,[])
link(onDelete,15487727:doData,[(331,391)(331,454)])
link(Op1,10884471:Var1,[(286,366)(321,366)(321,429)])
}
BEGIN_SDK
Add(EditMultiEx,12370993,21,21)
{
WorkCount=#5:##add|8:doDelete|7:##clear|
EventCount=#8:onResult|8:onDelete|
DataCount=#3:Op1|
Point(##add)
Point(##clear)
link(##add,14089078:doTimer,[(70,27)(70,48)])
link(doDelete,8262538:doEvent1,[(42,34)(42,97)])
}
Add(Math,9128440,231,42)
{
Op2=1
link(onResult,12370993:onResult,[(285,48)(285,27)])
link(Op1,12370993:Op1,[(237,32)(27,32)])
}
Add(Hub,8262538,63,91)
{
link(onEvent1,14089078:doStop,[(98,97)(98,55)])
link(onEvent2,12370993:onDelete,[(294,104)(294,34)])
}
Add(Timer,14089078,119,42)
{
Interval=15
Enable=1
link(onTimer,9128440:doOperation,[])
}
END_SDK
Add(Memory,14628342,350,378)
{
link(onData,6622035:doText,[])
}
Add(Label,6622035,399,378)
{
Left=10
Top=100
}
Add(Button,1463480,196,378)
{
Left=10
Top=120
TabOrder=-1
link(onClick,13664646:##add,[])
}
Add(Button,5614741,196,413)
{
Left=10
Top=145
TabOrder=-1
link(onClick,13664646:doDelete,[(254,419)(254,391)])
}
Add(MultiElementEx,9260267,280,238)
{
link(onResult,5960612:doValue,[])
link(onDelete,9260267:##clear,[(332,251)(332,285)(268,285)(268,258)])
link(Op1,5960612:Value,[(286,226)(321,226)(321,289)(356,289)])
}
BEGIN_SDK
Add(EditMultiEx,11371213,21,21)
{
WorkCount=#5:##add|8:doDelete|7:##clear|
EventCount=#8:onResult|8:onDelete|
DataCount=#3:Op1|
Point(##add)
Point(##clear)
link(##add,7498319:doTimer,[(70,27)(70,48)])
link(doDelete,13853942:doEvent1,[(42,34)(42,97)])
}
Add(Math,8716678,231,42)
{
Op2=1
link(onResult,11371213:onResult,[(285,48)(285,27)])
link(Op1,11371213:Op1,[(237,32)(27,32)])
}
Add(Hub,13853942,63,91)
{
link(onEvent1,7498319:doStop,[(98,97)(98,55)])
link(onEvent2,11371213:onDelete,[(294,104)(294,34)])
}
Add(Timer,7498319,119,42)
{
Interval=15
Enable=1
link(onTimer,8716678:doOperation,[])
}
END_SDK
Add(Memory,5960612,350,238)
{
link(onData,10891551:doText,[])
}
Add(Label,10891551,399,238)
{
Left=10
Top=20
}
Add(DeferredEvent,12154801,399,448)
{
InData=0
link(onDeferredEvent,6227579:doEvent1,[])
}
Add(DoData,15487727,350,448)
{
Data=Integer(5)
link(onEventData,12154801:doDeferredEvent,[])
link(Data,10884471:Var2,[])
}
Add(Edit,8220547,490,448)
{
Left=80
Top=145
Width=120
Cursor=1
Text=""
}
Add(Hub,6227579,441,448)
{
link(onEvent1,8220547:doText,[])
link(onEvent2,13664646:##clear,[(469,461)(469,502)(268,502)(268,398)])
}
Add(GetDataEx,10884471,350,424)
{
link(Data,14628342:Value,[])
}

карма: 22

8
Голосовали:foksov, login, CriDos, sаmakacd, sla8a, ser_davkin, Assasin, Konst
Гость
Ответов: 17029
Рейтинг: 0
#2: 2012-04-03 17:18:47 правка | ЛС | профиль | цитата


Редактировалось 7 раз(а), последний 2021-06-21 04:17:43
карма: 0

0
Разработчик
Ответов: 26115
Рейтинг: 2126
#3: 2012-04-03 17:38:53 ЛС | профиль | цитата
г. 333 писал(а):
или не там смотрю?

Так то уже устарело пару лет назад. Вот тут надо искать -- http://svn.hiasm.com/packs/delphi/
------------ Дoбавленo в 17.38:
Кстати, вот еще та самая "любимая" ситуация, когда использовалось событие onCreate формы, и таймер ставился для полного отображения этой формы. Вот в этом примере, показано, что элесмент Message срабатывает до полного отображения формы



Add(MainForm,2953706,98,105)
{
link(onCreate,2435421:doMessage,[])
}
Add(Message,2435421,168,119)
{
}


И если поставить OtherQueueEvent, то форма отобразиться полностью



Add(MainForm,2953706,98,105)
{
link(onCreate,8092189:doOtherQueueEvent,[])
}
Add(Message,2435421,217,119)
{
}
Add(OtherQueueEvent,8092189,154,119)
{
link(onOtherQueueEvent,2435421:doMessage,[])
}


Вот интересно слышать бы мнение -- нужно ли предусмотреть задержку отработки выходного события, естественно, без использования таймера, применив Sleep(), те отдав на это время управление системе
Или лучше этого делать не стоит

карма: 22

0
Гость
Ответов: 17029
Рейтинг: 0
#4: 2012-04-03 17:45:20 правка | ЛС | профиль | цитата


Редактировалось 7 раз(а), последний 2021-06-21 04:17:43
карма: 0

0
Гость
Ответов: 17029
Рейтинг: 0
#5: 2012-04-03 17:47:04 правка | ЛС | профиль | цитата


Редактировалось 7 раз(а), последний 2021-06-21 04:17:41
карма: 0

0
Ответов: 1061
Рейтинг: 22
#6: 2012-04-03 17:53:02 ЛС | профиль | цитата
nesco, спасибо! Была такая проблемка!
карма: 0

0
Разработчик
Ответов: 26115
Рейтинг: 2126
#7: 2012-04-03 17:58:22 ЛС | профиль | цитата
г. 333 писал(а):
А еще есть у этого элемента применения или он просто костыль?

Считай, что это глобальный костыль.
г. 333 писал(а):
А может его в ##сlear контейнеров запихать (если это возможно)

Вот туда мы пихать точно ничего не будем, не стоит наращивать код, там где это не нужно, не всегда используется ##delete и ##clear

Хочу предупредить, что это пока бета версия. Я думаю отвязать этот элемент от апплета, тк при мультипоточном применении, при такой реализации, возможно появление ошибки. Надо бы попробовать поймать такой режим, но пока у меня нет вариантов реализации тестовой схемы. Но отвязка от апплета потащит на себя создание окна обработчика в каждом классе элемента, другой реализации я пока не вижу. Вот почему и не тороплюсь этого делать
------------ Дoбавленo в 17.58:
Есть у кого какие мысли по озвученной теме
карма: 22

0
Ответов: 3889
Рейтинг: 362
#8: 2012-04-03 18:31:13 ЛС | профиль | цитата
nesco писал(а):
интересно слышать бы мнение -- нужно ли предусмотреть задержку отработки выходного события, естественно, без использования таймера, применив Sleep()
nesco писал(а):
Есть у кого какие мысли по озвученной теме
sleep() он и без отдельного потока пригодится, как не грузящая несчастный процессор альтернатива малопопулярному hiSleep с его примитивным циклом. Тогда элемент будет более чем оправдан.
карма: 1

0
Ответов: 8923
Рейтинг: 823
#9: 2012-04-03 18:37:24 ЛС | профиль | цитата
nesco, а большая-ли разница между новым OtherQueueEvent и Потоком, и что значит "большого количества таймеров для целей разделения событий по времени", заменяем большим количеством OtherQueueEvent-ов или есть более весомые преимущества code_27525.txt
карма: 19

0
файлы: 1code_27525.txt [2.5KB] [291]
Ответов: 1061
Рейтинг: 22
#10: 2012-04-03 18:52:13 ЛС | профиль | цитата
Леонид, в OtherQueueEvent ещё и данные передаются, что может уменьшить схему на несколько компонентов!
карма: 0

0
Разработчик
Ответов: 26115
Рейтинг: 2126
#11: 2012-04-04 01:18:59 ЛС | профиль | цитата
Леонид писал(а):
а большая-ли разница между новым OtherQueueEvent и Потоком

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

Короче, OtherQueueEvent -- глобальное отложенное событие
------------ Дoбавленo в 20.25:
1nd1g0 писал(а):
sleep() он и без отдельного потока пригодится

А у меня и нет отдельного потока, все в рамках обработчика главного потока
------------ Дoбавленo в 20.28:
Леонид писал(а):
"большого количества таймеров для целей разделения событий по времени"

События не совсем разделяются по времени, скорее -- по очередям выполнения, отложенное событие выполняется в другой очереди сообщений, давая возможность закончить предыдущую цепь событий схемы
------------ Дoбавленo в 01.18:
Имя компонента заменено на DeferredEvent (отложенное событие) и переведено на собственные обработчик специального окна только для сообщений. Переведен из вкладки Контролы во вкладку Система. Введена задержка перед запросом на выдачу отложенного события. Теперь компонент можно использовать как Sleep с разрешением в одну миллисекунду.

Все изменения уже на SVN
карма: 22

5
Голосовали:foksov, 1nd1g0, miver, Konst, filyaxxxcom
Ответов: 1376
Рейтинг: 197
#12: 2012-04-16 16:32:52 ЛС | профиль | цитата
nesco, а нельзя-ли в DeferredEvent ещё добавить верхнюю точку для принятия индекса, чтоб убрать предшествующий перед ним DoData?
code_27667.txt
карма: 1

0
файлы: 1code_27667.txt [1KB] [448]
Разработчик
Ответов: 26115
Рейтинг: 2126
#13: 2012-04-16 17:02:26 ЛС | профиль | цитата
foksov писал(а):
ещё добавить верхнюю точку для принятия индекса

Ну, положим не индекса, а данных, это у тебя в схеме индекс. Кончно можно, а почему бы и нет
------------ Дoбавленo в 17.02:
Добавил
карма: 22

3
Голосовали:foksov, sаmakacd, Konst
Ответов: 2237
Рейтинг: 676
#14: 2012-04-18 17:13:54 ЛС | профиль | цитата
nesco, а можно к элементу добавить, чтобы при использовании задержки события (Delay > 0), не создавалось новое событие пока не произойдет уже созданное?
На примере code_27688.txt это должно работать так: в секунду одно событие на нажатие кнопки в независимости от того сколько раз за секунду успел нажать кнопку пользователь.
карма: 11

0
файлы: 1code_27688.txt [583B] [352]
Ответов: 8923
Рейтинг: 823
#15: 2012-04-18 17:29:47 ЛС | профиль | цитата
sla8a, code_27689.txt
карма: 19

1
файлы: 1code_27689.txt [686B] [280]
Голосовали:Tad
Сообщение
...
Прикрепленные файлы
(файлы не залиты)