Vista и DoEvents

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

Vista и DoEvents

Сообщение CodeName33 » 18.02.2009 (Ср) 10:04

Утро доброе.

Такой вопросец возник: Есть программа, в ней цикл, который идёт достаточнро долго. Программа показывает прогресс в процентах. В XP и ранних версиях в цикле работало:
Код: Выделить всё
Sleep 1
DoEvents

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

Был в своё время такой код:
Код: Выделить всё
Dim M As Msg

If GetMessage(M, hwnd, 0, 0) Then
  TranslateMessage M
  DispatchMessage M
End If

Но он работает достаточно криво, когда к окну нет обращений.
Программисты не глючат - глючат компиляторы...

|kerish|
Постоялец
Постоялец
 
Сообщения: 831
Зарегистрирован: 22.10.2004 (Пт) 0:31

Re: Vista и DoEvents

Сообщение |kerish| » 18.02.2009 (Ср) 12:07

А зачем тебе вообще Sleep?

Он только вешает твою программу.

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Re: Vista и DoEvents

Сообщение CodeName33 » 18.02.2009 (Ср) 12:21

|kerish| писал(а):А зачем тебе вообще Sleep?
Он только вешает твою программу.


Помнится во времена Win98 слишком частые вызовы DoEvents грузили систему в целом так, что становилось тяжело работать со сторонними приложениями, пока моё приложение крутилось в фоне. Выход был найден - использовать перед DoEvents Sleep с минимальным интервалом. Сейчас этот вызов в любом случае мою программу не вешает, т.к. DoEvents выполняется не чаще, чем 4-5 раз в секунду ввиду того, что там другие вычисления ещё идут, а не пустой цикл крутится :) В любом случае, если убрать Sleep проблема остаётся.
Программисты не глючат - глючат компиляторы...

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

Re: Vista и DoEvents

Сообщение arthur2 » 18.02.2009 (Ср) 14:06

CodeName33 писал(а):слишком частые вызовы DoEvents грузили систему в целом так <...>
DoEvents выполняется не чаще, чем 4-5 раз в секунду ввиду того, что там другие вычисления ещё идут, а не пустой цикл крутится


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

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Re: Vista и DoEvents

Сообщение CodeName33 » 18.02.2009 (Ср) 14:34

arthur2 писал(а):
CodeName33 писал(а):Вообще-то, по-моему, дуэвент не грузит, а разгружает систему (попробуй его совсем убрать для пробы :)
А если за четверть секунды нет ни одного дуэвента, то это-то как раз и вешает систему. За эти четверть секунды ни кнопку кликнуть, ни окно подвигать


DoEvents ничего не разгружает. Он просто позволяет сообщениям доходить до окон моего приложения и обрабатываться там. Цикл вида:
Код: Выделить всё
Do
    DoEvents
Loop

в Win98 очень загружет систему (не моё приложение, а всю систему) в других приложениях было не возможно работать, пока такой цикл выполняется. С Sleep с минимальным интервалом перед DoEvents - всё было нормально. В 2К/XP это исправлено, и этот цикл будет работать нормально, как с Sleep, так и без него (возможно это потому, что железо с тех пор стало пошустрее).
Программисты не глючат - глючат компиляторы...

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Vista и DoEvents

Сообщение ANDLL » 18.02.2009 (Ср) 14:34

Вообще-то, по-моему, дуэвент не грузит, а разгружает систему

Нет, глупость несусветная. DoEvents именно что грузит систему
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

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

Re: Vista и DoEvents

Сообщение arthur2 » 18.02.2009 (Ср) 14:47

CodeName33
Не знаю, но по-моему, если дуэвент всего лишь четыре раза в секунду, это слишком редко для того, чтобы "сообщения доходили до окон моего приложения", поэтому-то время от времени и кажется, что твои окна на эти сообщения не отвечают. Проверь, что тебе мешает? С оставленным слипом :)

ANDLL Глупость-не глупость, а без дуэвента система так загрузится, что мало не покажется.

Могу попробовать сформулировать по-другому: дуэвент разгружает программу за счёт нагрузки на систему. Так правильней?
Артур
 
   

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

Re: Vista и DoEvents

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

Вот простенький эксперимент, имитирующий описанную проблему. Дуэвент в цикле раз в четверть секунды. На форме текстовое поле. Печатать в нём - совершенно невозможно. Может, статус на "не отвечает" и не меняется (у меня ХР), но по ощущениям - как раз что тормозит и вот-вот отвалится :)
Код: Выделить всё
Option Explicit
Private Declare Function GetTickCount Lib "kernel32.dll" () As Long
Dim flExit As Boolean
Private Sub Form_Click()
  Dim ln As Long
  ln = GetTickCount
Do
  Do While GetTickCount - ln < 250
  Loop
  DoEvents
  ln = GetTickCount
  If flExit Then Exit Do
Loop

End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
  flExit = True
End Sub

Private Sub Text1_KeyPress(KeyAscii As Integer)
  Caption = Chr(KeyAscii)
End Sub

Артур
 
   

Денис
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2734
Зарегистрирован: 07.11.2006 (Вт) 13:55
Откуда: Ейск, Краснодарский край

Re: Vista и DoEvents

Сообщение Денис » 18.02.2009 (Ср) 15:18

CodeName33

А почему именно в цикле, а не по таймеру?
Программирование — богоизбранная дисциплина! Если бог и есть, то вселенную он скомпилировал, не иначе.

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Re: Vista и DoEvents

Сообщение CodeName33 » 18.02.2009 (Ср) 15:24

arthur2 писал(а):Вот простенький эксперимент, имитирующий описанную проблему...


Это не проблема. Мне не нужно, чтобы пользователь ничего делал в моём приложении, пока выполняется цикл, мало того, там все контролы дизаблятся на это время. DoEvents нужен для того, чтобы приложение не повисало, а прогресс бар обновлялся (в Win98 это работало и без DoEvents, но зато задачу там так просто с зависшего приложения было не снять). Но похоже я выяснил в чём дело. Действительно, Виста почемуто достаточно быстро проверяет приложение на предмет зависло оно или нет. Если вызывать DoEvents почаще (5 раз в секунду и чаще) приложение не помечается зависшим и прогресс нормально отображается на экране.

Тему можно закрывать.
Программисты не глючат - глючат компиляторы...

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Re: Vista и DoEvents

Сообщение CodeName33 » 18.02.2009 (Ср) 15:24

Денис писал(а):CodeName33

А почему именно в цикле, а не по таймеру?


По таймеру медленнее выходит и геморройнее код.
Программисты не глючат - глючат компиляторы...

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

Re: Vista и DoEvents

Сообщение alibek » 18.02.2009 (Ср) 15:33

По таймеру правильнее. Да и проще, на самом деле, если грамотно делать.
Lasciate ogni speranza, voi ch'entrate.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Re: Vista и DoEvents

Сообщение ANDLL » 18.02.2009 (Ср) 15:37

Код: Выделить всё
Так правильней?
Нет. DoEvents - обрабатывает сообщение в очереди если таковое есть, вообще ничего не разгружая.
Может, статус на "не отвечает" и не меняется (у меня ХР), но по ощущениям - как раз что тормозит и вот-вот отвалится
Потому что при простом цикле сообщения скапливаются в очереди. А вовсе не потому что система сильно перегружена.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Re: Vista и DoEvents

Сообщение CodeName33 » 18.02.2009 (Ср) 15:39

alibek писал(а):По таймеру правильнее. Да и проще, на самом деле, если грамотно делать.


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

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

Re: Vista и DoEvents

Сообщение alibek » 18.02.2009 (Ср) 15:44

CodeName33 писал(а):Надо просто переделывать простой код, который в цикле выполняется, под таймер, отчего он усложнится, к томуже с таймером медленнее получается.

Это от того, что ты изначально сделал неправильно.
Прогресс надо менять в таймере, а основной цикл, в котором выполняется длительная операция, будет просто изменять значения переменных, отражающих прогресс.
Lasciate ogni speranza, voi ch'entrate.

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Re: Vista и DoEvents

Сообщение CodeName33 » 18.02.2009 (Ср) 15:48

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


Таймер всё-равно не сработает, пока не случится DoEvents в основном цикле. Получается тоже самое, как оно сейчас. Я думал речь идёт о выполнении цикла таймере, где срабатывание таймера будет равно n-ному числу итераций.
Программисты не глючат - глючат компиляторы...

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

Re: Vista и DoEvents

Сообщение alibek » 18.02.2009 (Ср) 16:32

Пусть так, но это логически более правильно, и фрагмент отрисовки прогресса будет более автономным.
Lasciate ogni speranza, voi ch'entrate.

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Re: Vista и DoEvents

Сообщение CodeName33 » 18.02.2009 (Ср) 16:38

alibek писал(а):Пусть так, но это логически более правильно, и фрагмент отрисовки прогресса будет более автономным.


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

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

Re: Vista и DoEvents

Сообщение arthur2 » 18.02.2009 (Ср) 17:12

Но похоже я выяснил в чём дело Действительно, Виста почемуто достаточно быстро проверяет приложение на предмет зависло оно или нет. Если вызывать DoEvents почаще (5 раз в секунду и чаще) приложение не помечается зависшим и прогресс нормально отображается на экране.

Здрасьте, пожалуйста, а я о чём? Может конечно я как-то не так формулирую, но именно это я и имел ввиду с самого начала :)

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

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

Re: Vista и DoEvents

Сообщение arthur2 » 18.02.2009 (Ср) 17:17

ANDLL писал(а):Нет. DoEvents - обрабатывает сообщение в очереди если таковое есть, вообще ничего не разгружая.

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

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Re: Vista и DoEvents

Сообщение CodeName33 » 18.02.2009 (Ср) 17:22

arthur2 писал(а):
Но похоже я выяснил в чём дело Действительно, Виста почемуто достаточно быстро проверяет приложение на предмет зависло оно или нет. Если вызывать DoEvents почаще (5 раз в секунду и чаще) приложение не помечается зависшим и прогресс нормально отображается на экране.

Здрасьте, пожалуйста, а я о чём? Может конечно я как-то не так формулирую, но именно это я и имел ввиду с самого начала :)

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

Совсем другой смысл. Сообщения доходят замечательно и в полном объёме. Просто Виста слишком быстро считает поиложение зависшим. Под XP такого нет, даже если поставить 1 DoEvents в секунду. Как только DoEvents выполнится - приложение отвисает. В Висте, если приложение трудится в фоне, то оно 1 раз зависает и уже потом чтобы оно отвисло приходится переприменять настройки рабочего стола, без этого оно не отвисает даже по DoEvents. Периодически подвисает-отвисает оно только в том случае, если оно активно. В XP всё-равно в фоне/не в фоне, оно вообще не подвисает и обновляется с той частотой, с кторой происходит DoEvents, если его не тыркать мышкой усиленно.
Программисты не глючат - глючат компиляторы...

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

Re: Vista и DoEvents

Сообщение arthur2 » 18.02.2009 (Ср) 17:29

Совсем другой смысл. Сообщения доходят замечательно и в полном объёме.

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

Я
системе кажется, что твои окна на эти сообщения не отвечают

В чём разный смысл?

Я что-то напутал в терминах? так я их вроде и не использовал ни каких терменов. А в чём причина - я тебе сказал сразу же: в слишком редких дуэвентах.

Если, скажем, шутка доходит "замечательно и в полном объёме", но на следующий день, то это и значит, что она не доходит :)
Артур
 
   

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Re: Vista и DoEvents

Сообщение CodeName33 » 18.02.2009 (Ср) 17:45

arthur2 писал(а):Я что-то напутал в терминах? так я их вроде и не использовал ни каких терменов. А в чём причина - я тебе сказал сразу же: в слишком редких дуэвентах.

Если, скажем, шутка доходит "замечательно и в полном объёме", но на следующий день, то это и значит, что она не доходит :)

Тут смысл в том, что в XP, когда сообщения доходят - приложение отвисает, не зависимо от того в фоне оно или активно. А в Висте если оно зависает в фоне, то оно уже само не отвисает, даже после DoEvents. К томуже в XP оно само не зависает, если не трогать щёлкать его и не просить перерисовываться.
Программисты не глючат - глючат компиляторы...

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

Re: Vista и DoEvents

Сообщение arthur2 » 18.02.2009 (Ср) 19:16

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

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

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Re: Vista и DoEvents

Сообщение CodeName33 » 18.02.2009 (Ср) 21:07

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

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


Просто XP не чекает прогу, пока юзер не пытается к ней обратиться, а Виста по ходу чекает. Чем реже я рисую на экране, тем больше за это время выполнится полезного кода. Юзеру всё-равно, ему достаточно обновления прогресса раз в секунду, учитывая, что вся операция занимает минут 5-10. А вот Виста вынуждает делать обновление чаще, что мне в ней не очень нравится. Кстати если выполнять код:
Код: Выделить всё
For i =1 To 255
    DoEvents
Next

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

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

Re: Vista и DoEvents

Сообщение arthur2 » 18.02.2009 (Ср) 21:20

ну, значит не количество, а всё же время :)

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

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

CodeName33
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 297
Зарегистрирован: 01.09.2004 (Ср) 13:25
Откуда: SPb

Re: Vista и DoEvents

Сообщение CodeName33 » 18.02.2009 (Ср) 22:13

arthur2 писал(а):...А подвисшей, или, как ты описывал, наглухо застрявшей?...


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

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

Re: Vista и DoEvents

Сообщение arthur2 » 18.02.2009 (Ср) 22:43

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

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


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

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

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

    TopList  
cron