Замораживание таймера при нажатии мышью на скроллбаре

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

Сообщение arthur2 » 01.08.2008 (Пт) 10:00

Хакер
Не возникает никакая рекурсия. Ни при таскании, ни при вызове меню, ни как.

Я вообще бросил на форму пять вебешных таймеров, которые, по идее, должны поставлять события дуэвентсу (вместо скрола) - не появляется рекурсяия. И от скрола не появляется.

То что каждый второй тик холостой, можно исправить, выставляю на каждом втором тике интервал в ноль (а на первом возвращая).

Изначально ты говорил не о непременимости этого бредового кода, а о его НЕОСУЩЕСТВИМОСТИ.
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 01.08.2008 (Пт) 10:10

Я вообще бросил на форму пять вебешных таймеров, которые, по идее, должны поставлять события дуэвентсу (вместо скрола) - не появляется рекурсяия. И от скрола не появляется.


То что ты это пишешь, ещё раз говорит от том, что ты не понимаешь, к чему здесь скрол и что происхолит в его WP.

То что каждый второй тик холостой, можно исправить, выставляю на каждом втором тике интервал в ноль (а на первом возвращая).

Здесь холостой означает, что ты не вызываешь DoEvents и не инициируешь рекурсию.

Изначально ты говорил не о непременимости этого бредового кода, а о его НЕОСУЩЕСТВИМОСТИ.

Я говорил, что нельзя сделать сделать так, чтобы и в таймере код работа и скролл работал. Одновременно они работать не могут, а последовательно — только рекурсивно.

Ты так и не осуществил, т.е. не сделал такой код, который бы работал так, как надо (такого кода не существует), но сделал другой, который работает не так как надо, но и не так, как ты изначально говорил.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 01.08.2008 (Пт) 10:22

Хакер писал(а):Я говорил, что нельзя сделать сделать так, чтобы и в таймере код работа и скролл работал.

Зависит от, в некоторых случаях можно.
Lasciate ogni speranza, voi ch'entrate.

amer
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 108
Зарегистрирован: 02.08.2003 (Сб) 19:41
Откуда: Воронеж

Сообщение amer » 02.08.2008 (Сб) 3:11

извините, а почему автор вообще использует таймер?
может просто в цикле все делать?
типа:
Do
получить данные
DopEvents
обработать данные
DopEvents
нарисовать графики
DopEvents
Loop

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 03.08.2008 (Вс) 1:07

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

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 03.08.2008 (Вс) 9:21

Arkadia
Твоя программа и так сидит в большом цикле. Пойми это. Разница лишь в том, что ты делаешь в нём.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 04.08.2008 (Пн) 2:18

Но это цикл не моего (прикладного) уровня, и я им не озабочиваюсь, и за него не отвечаю и не хочу отвечать - это системные дела, которые, как я надеюсь, сделаны наиболее правильно (не считая обсуждаемого глюка с таймером).
Я максимально стараюсь использвать событийный, объектный метод организации программы, как и советовал где-то тут Хакер.
Зачем мне самостоятельно писать (циклами, или еще чем-то) то, что предоставляет система в виде таймера? Таким путем можно и до собственной ОС дойти...
Пока что самая длинная обработка у меня длится неск.сотен мс на P166MMX (ниже не разрешу). Такое время отклика на действия пользователя - терпимо. Если же прижмет - я нашел решение: в первом таймере делать часть обработки, описывать оставшиеся этапы обработки, и запускать новый таймер, который эти этапы будет перемалывать в своих событиях timer. Поскольку внутри таймеров не будет doevents, обсуждаемого глюка не будет. А в интервалах между таймерами будут проскакивать все текущие дела, которые я первоначально пускал doevents-ами.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 04.08.2008 (Пн) 10:31

Хакер
Я говорил, что нельзя сделать сделать так, чтобы и в таймере код работа и скролл работал. Одновременно они работать не могут, а последовательно — только рекурсивно.
Я изначально это понял. Поэтому и предложил не как разрешить это противоречие (оно действительно неразрешимо), а как его обойти.

Попытаюсь сформулировать проблему, чтобы понятней было, как именно я хочу её решить.

Есть некий цикл обработки данных.
В нём есть doevents, чтобы позволить юзеру что-нибудь сделать.
Но когда юзер делает это что-нибудь, цикл приостанавливается.
И это неизбежно. Добиваться, чтобы цикл не приостанавливался, бесполезно.

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

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

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

Код: Выделить всё
Private Sub ITimer_Tick(ByVal idTimer As Long, tmNow As Long)

Select Case idTimer
Case tm1
  tick1 tmNow
Case tm2
  tick2 tmNow
End Select

End Sub

Private Sub tick1(tmNow As Long)' интервал 1000
Static fKRB As Boolean
If fKRB Then Exit Sub
  fKRB = True
  Dim tm As Long
  Do
     mTimer.Enabled(tm2) = True' запускаем вспомогательный таймер на случай, если обработка событий затянится.
     DoEvents
     mTimer.Enabled(tm2) = False' останавливаем вспомогательный таймер
     Call DoSomething
     tm = GetTickCount
     If tm > tmNow + 800 Then Exit Do 'немного меньше интервала, потому что иначе
                                      'при срабатывании КРБ таймер будет ждать целую секунду лишнюю
  Loop
  fKRB = False
End Sub

Private Sub tick2(tmNow As Long)' интервал 50
    Debug.Print "из тика";
    Call DoSomething
End Sub


Private Sub DoSomething()
  Dim s As String
  s = Space(1000000) & Space(1000000)
  cntSomething = cntSomething + 1
  Debug.Print cntSomething
End Sub

На этот раз КРБ, как видешь, стандартная. Недостаток - dosomething по таймеру, естественно, будет вызываться несколько реже, чем в непрерывном цикле.

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

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 04.08.2008 (Пн) 13:35

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

А в примере цикл я кручу такое же время, как и интервал таймера, в демонстрационных целях: чтобы из ста нажатий на ползунок или заголовок формы 50 раз таймер застрял, а другие 50 раз - продолжил работу.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 04.08.2008 (Пн) 14:04

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

Для чего тебе нужна пауза - не понятно.
а таймер обеспечит гарантированный интервал, в течение которого а) данные индицируются
Если данные индецируются в обработчике тика, то тогда во время интервала вообще ничего не делается.
б) могут делаться другие дела (по событиям от пользователя и по другим таймерам)
Для этого тебе нужна целая секунда простоя? Тем более, что эта секунда может растенуться на сколько угодно, если в момент обработки вызвать меню (это ведь и есть проблема?)
Артур
 
   

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 05.08.2008 (Вт) 1:11

Данные в обработчике тика выводятся на экран. Затем они там должны постоять 50-300 миллисекунд, чтобы человек их увидел - нет смысла обновлять 100 раз в секунду.
Секунда простоя нужна только в первом примере - чтобы можно было поймать момент, когда захват мышью заголовка окна не морозит таймер.
Торможение обмена из-за операций с меню - не проблема, так и должно быть: действия человека имеют приоритет над потоком. Проблема была в другом: если человек лезет в меню в момент, когда событие таймера работает - то меню виснет (не даёт событий и не закрывается). Но эта проблема исчезла (вместе с остальными проблемами) как только я по наводке Хакера убрал все doevents из процедур события таймера.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 05.08.2008 (Вт) 13:30

Arkadia
Ты пишешь, что обработка может длиться неопределенное время. В таком случае, интервалы стандартного таймера будут неравномерны, а апишного - равномерны. То есть, если обработка затянется на секунду, следующий тик произойдёт через две секунды (а у апишного - всё равно через секунду). Собственно, для твоей задачи (раз нет больше дуевентса), это будет единственным отличием. И если обработка всегда в пределах 100-200 миллисекунд, разницы действительно никакой.
Артур
 
   

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 06.08.2008 (Ср) 2:40

Нет, у меня сколько бы не длилась обработка - следующий тик произойдет после нее через столько миллисекунд, сколько задано в interval. И это - правильное поведение таймера, ибо минимальный гарантированный зазор должен быть, хотя бы - чтоб в меню полазить, скролл потаскать. А если APIшный таймер будет лупить сразу по выходу из предыдущего - то когда ж остальные события проскочат?

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 06.08.2008 (Ср) 11:56

Вб-таймер - тикнет ровно через секунду после конца обработки предыдущего тика.
Апи-таймер - тикнет ровно через секунду после срабатывания предыдущего тика.

Вб-таймер натикает за минуту неизвестно сколько - зависит от времени обрабоки тиков.
Апи-таймер за минуту натикает ровно 60 раз.

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

Впрочем, разница всё же есть: если вызвать модальное окно, вб-таймер остановится по-любому, хоть с дуэвентсами, хоть без (или таймер нужно класть на ту форму, которая будет показана как модальная, что не пройдёт, например, с msgbox). А апишном это по барабану
Последний раз редактировалось arthur2 06.08.2008 (Ср) 12:11, всего редактировалось 1 раз.
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 06.08.2008 (Ср) 12:07

arthur2
Противопоставлять VB-таймеру API-таймер по меньщей мере глупо. Противопоставляй ему самодельный таймер.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 06.08.2008 (Ср) 12:13

Если API таймер тикает рекурсивно - то мне это не подходит однозначно. Если же он тикает после окончания предыдущей своей работы - то зазора не будет: обработка у меня до cекунды, а вот интервал между ними намного меньше должен быть. То есть время обработки превысит заданный таймеру интервал, и он тикнет сразу после окончания предыдущего.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 06.08.2008 (Ср) 12:15

Хакер
Я не противопоставляю, а сравниваю. Понятно, что вбшный сделан из апишного - это ты хотел возразить? Свойства апишного изначальны. Свойства вебешного - привнесённые.

Arkadia
Я не уговариваю тебя за апи-таймер - говорю же, что в твоём случае без разницы.

Апи-таймер не будет тикать рекурсивно, если в тиках нет дуэвента.
Апи-таймер не будет тикать рекурсивно, если в тиках по этому поводу выставить флаг.
Артур
 
   

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 06.08.2008 (Ср) 12:28

Arkadia

обработка у меня до cекунды, а вот интервал между ними намного меньше должен быть

Ну а я тебе о чём? У вебешного именно интервал между обработками всегда одинаковый (внутри тот же апишный, но на время обработки он, видимо, останавливается). А у Апишного - одинаковый интервал как раз между тиками.
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 06.08.2008 (Ср) 12:28

Нет у апишного никаких свойств. Единственное, что есть в windows-таймере, так это возможность фигачить в MQ потока сообщения WM_TIMER.

А то, как ты их обрабатываешь — свойства твоего кода, а не свойства таймера.
То, что ты написал, что базовому таймеру по барабану модальность — бред. Т.е. она ему действительно по барабану, он работает и в том случае, когда ты его ручками просишь, и когда он работает внутри VB-таймера.

А вот возможность обрабатывать тик или нет, это уже выбор программиста, не надо её связывать с фичастостью той или иной технологии.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 06.08.2008 (Ср) 12:39

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

Слово "свойства" по отношению к апи-таймеру предлагаю читать как "особенности", дабы не конфликтовало с термином "свойства".

А то, как ты их обрабатываешь — свойства твоего кода, а не свойства таймера.
А если никак не обрабатываю? То, как система вызывает следующий timeproc - можно считать-таки особенностью именно апи-таймера?

И перестань ты наконец "бред" да "бред".
Последний раз редактировалось arthur2 06.08.2008 (Ср) 13:25, всего редактировалось 1 раз.
Артур
 
   

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 06.08.2008 (Ср) 13:20

arthur2 писал(а): А у Апишного - одинаковый интервал как раз между тиками.

при одинаковом интервале между тиками - свободное время будет зависеть от времени обработки. То есть: или будет слишком много его (а это уменьшит скорость прихода данных, то есть девайс будет простаивать), или, наоборот, обработки полезут без интервала. Поэтому фиксированные 30-100мс зазора - нормально и с точки зрения загрузки проца, и с точки зрения потока данных, и для инерционности зрения.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 06.08.2008 (Ср) 13:24

Думаю, что "апишный таймер" - это всё-таки не термин с устоявшимся значением. Почему бы для простоты выражения не называть этим "термином" простую реализацию таймера, построенную на апи и процедуре косвенного вызова?


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

Во-первых, АПИ это API, а API это Application Programming Interface. Интерфейс прикладного программирования. Интерфейс программирования приложений.

И та же DoEvents имеет больше причин называть апишкой, чем KiFastSystemCallRet.

Что тогда такой "апишный таймер". "Таймер, основнанный на интерфейсе прикладного программирования"? Так уж извини, чем VB-шный таймер не походит под такое определение "апишного таймера"?


простую реализацию таймера, построенную на апи и процедуре косвенного вызова?

Нет ни простой, ни сложной реализации. Есть реализация Артура2, есть реализация Microsoft-а. Меня корёжит от того, что когда ты говоришь "апишный таймер", ты не только говоришь фигню (ну это простительно, полмира говорит похожую фигню), ты предполагаешь свою особую методику пользования им.

Ты говишь что-то вроде следующего: "VB-шный таймер обламывается на модальных формах, а апишному это не страшно.". Это и есть бред. Не страшно не API-шному таймеру, а не страшно тому механизму обработки тиков, который сконструировал ты. Не страшна модальность не самому таймеру, а тому, как ты его используешь.

Ты говоришь API-таймер, а предполагаешь не столько сам таймер, сколько то, что ты укажешь при его созданании.

Так что я советую говорить тебе: API-таймер, созданный с указанием того-то и сего-то вместо просто "API-таймер", и API-таймер, созданный с указанием этого и того вместо "VB-шный таймер".

Но, для простоты, я уже рекомендовал тебе говорить "самодельный" и "VB-шный".

Добавлено:
Слово "свойства" по отношению к апи-таймеру предлагаю читать как "особенности", дабы не конфликтовало с термином "свойства".

У него нет особенностей. Особенности вытекают из специфики его использования. А использовать его можно десятком разных способов.

Ты говоришь о каком-то одном из них, обобщая его на весь механизм таймеринга.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 06.08.2008 (Ср) 13:39

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


Хакер
Но, для простоты, я уже рекомендовал тебе говорить "самодельный" и "VB-шный"

Ок, пусть так.

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

http://bbs.vbstreets.ru/viewtopic.php?p=6699495#6699495

добавлено
У него нет особенностей. Особенности вытекают из специфики его использования. А использовать его можно десятком разных способов.


А то, как ты их обрабатываешь — свойства твоего кода, а не свойства таймера.

А если никак не обрабатываю? То, как система вызывает следующий timeproc - можно считать-таки особенностью именно апи-таймера?
Артур
 
   

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 07.08.2008 (Чт) 0:26

arthur2 писал(а):Поскольку, как выяснилось, задача у автора была вовсе не та, как в его первом тесте

Именно та. В тесте демонстрировалось, как подвисает таймер, если схватиться за скролл в событии таймера. Задача была - чтобы таймер не зависал. Задача решена удалением doevents из события таймера. Решение, парадоксальное на первый взгляд (поскольку привычно, что doevents вставляют для размораживания), появилось благодаря объяснению Хакера.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 07.08.2008 (Чт) 4:20

Arkadia
Проблема в тесте - как добиться, чтобы обработка данных в большом цикле не прерывалась, если дуэвентс затянулся и заморозил этот самый большой цикл.

В твоей конкретной задаче оказалось возможным вообще обойтись без дуэветнса. Это стало решением твоей конкретной задачи.

Но проблема интересна и сама по себе - вне зависимости от той конкретной задачи, которую ты решаешь.
Артур
 
   

Arkadia
Новичок
Новичок
 
Сообщения: 30
Зарегистрирован: 26.02.2006 (Вс) 15:23

Сообщение Arkadia » 07.08.2008 (Чт) 13:07

arthur2 писал(а):Arkadia
Проблема в тесте - как добиться, чтобы обработка данных в большом цикле не прерывалась, если дуэвентс затянулся и заморозил этот самый большой цикл.

Нет. Я, как старый ассемблерщик, тут солидарен с Хакером: если doevents затянулся - то он и должен затягивать всё то, откуда его запустили.
Моё недоумение было вызвано другим: почему doevents вообще затянулся? Что он такое ценное делал, что повис? При том, что другие таймеры (и их doevents-ы) на той же форме - продолжают работать. Я представлял doevents как пропуск очереди событий (то есть занимает конечное, небольшое, время). А он оказался зависающим на состоянии(нажатии мышью на заголовке формы/скроллбаре)

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 07.08.2008 (Чт) 16:34

если doevents затянулся - то он и должен затягивать всё то, откуда его запустили

Так оно и есть, и избежать этого невозможно - цикл замрёт, пока не обработается всё то, что его заморозило. Но можно попытаться это обойти, ведь:
другие таймеры <...> на той же форме - продолжают работать


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

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

Код: Выделить всё
Private Sub Form_Click()
    Do
         Call DoSomething 'выполняем нужные вычисления
         
         tmr.Enabled = True 'запускаем таймер на случай заморозки цикла
         DoEvents
         tmr.Enabled = False 'гасим таймер
         
         If flExit Then Exit Sub
    Loop
End Sub

Private Sub tmr_Timer()
    Debug.Print "из тика";
    Call DoSomething
End Sub

Private Sub DoSomething()
  Dim s As String
  s = Space(10000000) & Space(10000000) & Space(10000000) 'имитируем сложные вычисления
  cntSomething = cntSomething + 1
  Debug.Print cntSomething
End Sub

Private Sub Form_Unload(Cancel As Integer)
flExit = True
End
End Sub


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

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 07.08.2008 (Чт) 16:36

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

Опять же чушь. В тиках будет свой кэлфрейм со своими локальными переменными, отличными от тех, что были в главном цикле.

Уж если так хочется, обратись к фиберам, это будет хоть правильно.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

arthur2
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1688
Зарегистрирован: 23.01.2008 (Ср) 14:35

Сообщение arthur2 » 07.08.2008 (Чт) 17:06

Хакер
Я и из цикла, и из тика вызываю одну и ту же процедуру - с чего это в ней будут разные переменные?

А про фиберы я пытался читать, но так и не понял ни как, ни для чего ими пользоваться.
Артур
 
   

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 07.08.2008 (Чт) 17:08

Я и из цикла, и из тика вызываю одну и ту же процедуру - с чего это в ней будут разные переменные?

На эту глупость даже отвечать не хочется.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Пред.След.

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

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 42

    TopList