Forum Replies Created
-
AuthorPosts
-
PostscripterParticipantQuote:Возможно я нашел причину, но это может случаться только если закрывается сеанс Windows или каким-то другим способом форме поcылается сообщение WM_QUERYENDSESSION. Только при получении этого сообщения вызывается Application.ProcessMessages для того, чтобы отработали все таймеры перед закрытием.
Но при закрытии Windows WM_QUERYENDSESSION приходит перед закрытием приложения (ни один объект еще не освобожден и Application.Terminated = False)…
Вроде ничего предосудительного… Вряд ли проблема в этом. Вы смотрели строку номер 9828? Это ваш модуль, и при трассировке на этом операторе происходит Access Violation.
Quote:Я могу сделать дополнительно проверку Application.Terminated, возможно кто-то посылает это сообщение при освобождении объектов..Application.Terminated – вроде как не сообщение. А обработчик WM_QUERYENDSESSION у меня назначен, могу с точностью сказать – при завершении программы такого сообщения не приходит. Во всяком случае до уничтожения обработчика. При выключении компьютера – да, а при нормальном вызове TForm.close() – нет.
November 5, 2011 at 12:26 pm in reply to: Диалог без скина при проверке, запущено ли приложение #47123PostscripterParticipantВместо отображения непонятного диалога следовало бы послать предыдущему экземпляру программы сообщение, по которому оно выскочит в центр экрана. Ведь почему пользователь запускает вторую копию? Потому что потерял первую ^_^
PostscripterParticipantHello, Support!
Не удалось найти логического объяснения происходящему?
Ставить костыль, останавливать таймеры перед закрытием и ждать лучших времён?
Из скриншота видно – форма по OnClose уничтожала компоненты, дошла до компонента AlphaSkin (TsSkinManager), и тут почему-то “вдруг” сработали таймеры. Половины компонентов уже нет, ессно ничего хорошего не получилось. Вопрос – что такого делает деструктор этого самого AlphaSkin, что может вызвать обработку всех накопившихся сообщений и, следовательно, запуск таймеров?
Пробовал делать трассировку… Без исходников это конечно нелёгкое дело 🙂 Подскажите пожалуйста, в самых общих чертах, что делает строчка номер 9828 модуля acSBUtils.pas (последняя версия)? Эта процедура, состоящая из двух строк, и следующая за ней, состоящая из трёх строк, вызываются семь раз при уничтожении формы. Уже после того, как уничтожены визуальные компоненты формы, но до того, как сама форма и её невизуальные потомки уничтожатся полностью. На восьмой раз отрабатывает только строка 9827, а на 9828-й происходит Access Violation:
Сразу после этого срабатывают таймеры.
PostscripterParticipantДа у них везде тут одни ошибки 😡 …
Извиняюсь за флуд конечно, просто ситуация похожая – обновил программу – посыпались жалобы. Ошибки другие, но тоже, кстати, большинство на Win7. Приходится советовать отключать скины.
PostscripterParticipantВ продолжение переписки – http://forum.codenet.ru/archive/index.php/t-60036.html
Там тоже обсуждают таймеры и пишут что есть два варианта – тот, что используется в Delphi, работает на сообщениях и выполняется в порядке очереди. Но есть и ещё какой-то, когда система по истечению времени не посылает сообщение, а сразу вызывает указанную процедуру. Может вы это имели в виду… Но у меня этот способ не используется. Только стандартные TTimer.
PostscripterParticipantА нет, упала-таки! Всё, глюк вернулся :a7: Но только с одним из скинов – Wood.
Code:Можно мне зайти удаленно и посмотреть на все самому?Скачал TeamViewer (есть ещё LiteManager, он посимпатичней) — что дальше?
PostscripterParticipantО, вспомнил, что когда ошибка только появилась, я сделал копию, для экспериментов. Эта копия падала. Вот сейчас вернул её же на место – уже не падает. Не понимаю!
PostscripterParticipantДа, конечно. Но сейчас, правда, всё работает, поэтому смотреть особо не на что… 🙁
Quote:Не может, пакет не уничтожает компоненты.Но так есть, я ставил break на OnTimer и проверял Form1.ComponentCount. Обычно он равен 131, но после вызова Form1.Close – остаётся только 25. Может, пакет просто стал “последней каплей”, когда вся пирамида рухнула))) Во всяком случае, тут точно каким-то образом замешана моя dll-ка, без неё ошибку не удалось получить ни разу.
PostscripterParticipantА все OnTimer-ы и так выполняются в основном потоке…
PostscripterParticipantСпасибо, статья “годная” ^_^ , но последовательность и алгоритм возникновения бага мне известны (см. первое сообщение). Схема мне представляется такой:
Quote:При уничтожении формы сперва уничтожаются визуальные компоненты (всего было 131, стало 25), затем, вероятно, форма зачем-то обрабатывает накопившиеся сообщения (что-то типа application.ProcessMessages), при этом неуничтоженные таймеры выполняют ещё один цикл, пытаются обратиться к уже уничтоженным визуальным компонентам и вызывают access violation.
Вопрос только из-за чего так происходит и при чём тут библиотека. Грешу на недокументированную AppCertDlls… Может там ограничение на размер либы в памяти, всё-таки 460 кб – это немало… Так, например, многие модеры (и не только) любят понапихать в shell32.dll своих значков/картинок, в итоге она раздувается и занимает больше памяти чем ей выделено, и библиотека, следующая за ней, сдвигается. Многим программам сносит крышу. Может тут тоже что-то такое…
С этой моей библиотекой вообще мистика. На win7, пока она в памяти, невозможно запустить exe-шник, если его имя начинается с букв ADBERDR. При этом ни единой строчки кода не выполняется! Достаточно просто наличия этой библиотеки в реестре в разделе AppCertDlls!
PostscripterParticipantДело в том, что библиотека тоже на делфи, а в делфи работа с памятью поставлена очень хорошо. В сравнении с С++. Это раз, а второе – то что первой строчкой в коде библиотеки стоит чтение параметра из реестра, и если значение равно нулю, код не выполняется. Так что за это вряд ли можно зацепиться. В том коде, который не выполняется, происходит динамическое создание и отображение формы – диалогового окна. Эта форма не содержит компонентов AC.
PostscripterParticipantКонечно обновил!
С некоторыми из старых, кстати, работает, с некоторыми из новых – тоже. А с некоторыми – Access violation при закрытии. И так хаотично!!! То ошибка есть, а то её нет, и даже специально вызвать не получается.
Выяснил что это как-то связано с dll-библиотекой (часть программы), которая подгружается ко всем программам через ключ реестра AppCertDlls и отслеживает запуск приложений. Если она не загружена, то и ошибок нет. Но она не делает ничего такого, что можно было бы хоть как-то привязать к AlphaControls!! Я никак не могу найти связи. Библиотека отслеживает запуск программ, но не их завершение. А проблема именно при завершении. Код библиотеки несложный, ошибок в нём нет. И ведь всё работало с версией AC от 2010 года, покам я не обновился. Напасть какая-то…
Пока выходов два – откат до 2010 версии, либо остановка таймеров принудительно перед уничтожением формы. Оба варианта работают.
Мне кажется, небезосновательно, что сейчас при уничтожении формы сперва уничтожаются визуальные компоненты, затем форма обрабатывает накопившиеся сообщения (что-то типа application.ProcessMessages), при этом неуничтоженные таймеры выполняют ещё один цикл, и только потом уничтожаются невизуальные компоненты. Если эту ветку читают разработчики, скажите, AC может способствовать (теоретически) созданию такой ситуации?
PostscripterParticipantЧто интересно – не удаётся словить ошибку, если папку с программой переместить в другое место, например на рабочий стол.
PostscripterParticipantНет, я ошибся. Это помогло со скином Neutral3, а сейчас обнаружилось что скин Wood всё равно сбоит. А есть скины, не вызывающие сбоев при любом значении SkinnedPopup – например NextAlpha, Ubuntu, Deep purple.
PostscripterParticipantОтключение SkinnedPopup даёт нужный эффект – программа запускается и закрывается без ошибок.
-
AuthorPosts