| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Общие вопросы > A call to an OS function failed |
| Автор: ilya198293 30.5.2007, 08:58 | ||||
| В моём приложении несколько форм: из формы 1 вызываю форму 2:
при закрытии формы 2 стоит обработчик событий:
без такого обработчика форма не закрывается, а просто становится невидимой. последовательность открытия и закрытия делаю 24 раза и на 25 выходит сообщение "Error reading ComboBox1.Items.Strings: A call to an OS function failed." Причём первых 24 раза обрабатывается всё нормально. Результат работы формы 2 зависит от настроек формы 1. При разных настройках всё тоже работает, но до 25 раза. Что это значит и как это победить? |
| Автор: ama_kid 30.5.2007, 09:21 | ||||||
Это значит, что у тебя идет неправильная работа с памятью... Я с такой проблемой не сталкивался, ибо таким варварским способом не освобождал форму, навскидку вижу проблему в том, что у тебя из обработчика формы непосредственно идет вызов деструктора. А ведь сказано в хелпе:
|
| Автор: MetalFan 30.5.2007, 09:27 |
| так же добавлю, что нельзя убивать форму методом Free в обработчиках событий, описанных в ней же... для этого необходимо использовать метод Release. ну это так, на всякий случай для общего развития. в приведенном случае правильно делать так, как сказал ama_kid. |
| Автор: ilya198293 30.5.2007, 10:49 |
| Теперь ещё несколько моментов, которые возможно помогут прояснить ситуацию. В обработчике событий TForm1.FormCreate стоит запуск формы 8, в которой в два потока производится SQL запрос и прогон ProgressBar(зависит от времени - 20 сек - типа "подготовка к работе"). при завершении ProgressBar вызываю Form8.Close. При этом возвращаюсь в форму 1 и сразу делаю Form8.Free. В этом месте пробовал ставить обработчик TForm8.FormClose с текстом Action:=caFree, но тогда форма 8 закрывается (не знаю закрывается или просто становится невидимой), а форма 1 не визуализируется, а в диспетчере задач приложение остаётся (ресурсы при этом не жрёт).Так что пока оставил Form8.Free в тексте процедуры TForm1.FormCreate. Далее настройка всего в форме 1 и потом пошёл каскад открываний и закрываний формы 2. Поменял в TForm2.FormClose Form2.Free на Action:=caFree получил как и посоветовали - эквивалент Free (по крайней мере пока работает так как надо). Но ошибка осталась всё равно. По идее 24 раза она же почему-то отработала. |
| Автор: Rennigth 30.5.2007, 11:27 | ||
Ну так Action := caFree и вызывает в итоге Release.
|
| Автор: ilya198293 31.5.2007, 07:56 |
| Попробовал найти ошибки в программе просто создав новый проект и постепенно перенося процедуры из старого проекта...так столько ошибок повылезало...причём не могу понять как они в старом проекте проходили...например брал дату и конвертировал в строку в формате 'dd/mm/yy'. потом при раскладке считывал символы 1+2,4+5,7+8+9+10 и он считывал. в новом проекте даёт ошибку, причём логичную ошибку...ещё в нескольких местах такая же ерунда...когда считывалось из стринга больше символов чем там есть вообще...так что там нужно весь проект пересматривать... я по крайней мере грешу на установку всех сервиспаков и апдейтов...без них как-то логичнее всё работало, хотя и вылетали ошибки - ошибки у самого делфи, но не у разрабатываемого проекта. |
| Автор: ilya198293 31.5.2007, 09:38 | ||||
| Сейчас просто эксперементировал с двумя формами и получил такие результаты: Form1 Здесь форма создаётся как модальная, а в проекте нет, но сути это не меняет
Forma2
Ошибка появляется когда вводится проверка try в форме1. как ещё можно проверить существование формы (видимой и не видимой) для того, чтоб не запускать их несколько штук? |
| Автор: ama_kid 31.5.2007, 10:43 | ||||
Мысли проще:
Естессно, вторую форму желательно убрать из списка автосоздаваемых... |
| Автор: ilya198293 31.5.2007, 11:02 | ||
| Форма 2 из автосоздания убрана была. Когда проверка такая:
то второй раз нажать на кнопку на форме 1 не предоставляется возможным до тех пор пока она не закрыта...в этом случае try можно и не ставить, просто написать Action:=caFree; и всё. но в случае когда форма не модальная, тогда при нажатии плодятся новые формы...суть то всей задачи запретить открывать несколько вторых форм, но при этом иметь доступ к форме 1, из неё могут запускаться другие формы с такими же проверками. |
| Автор: MetalFan 31.5.2007, 11:20 | ||
руцки бы паатрыфалл за такое.... типа: ...."АГА!" сказали сибирские мужыки и пашли пилить дальше двуручной пилой |
| Автор: ama_kid 31.5.2007, 11:47 |
| MetalFan Что конкретно не нравится? Выстави просто флаг какой-нибудь при создании второй формы и сбрасывай при закрытии, а перед созданием - проверяй его. Или юзай мьютексы... |
| Автор: ilya198293 31.5.2007, 12:01 |
| О-о-о-о-о-о-о-о, а флаг это идея...как я сам не догадался...тармажу...спасибо |
| Автор: aktuba 31.5.2007, 12:12 | ||||
ЖЭСТЬ!!! Куда мир катиться... |
| Автор: MetalFan 31.5.2007, 12:17 |
| ama_kid, зачем доводить до того, что может возникнуть исключение? да еще и скорее всего AV. если можно обойтись, как ты сам и сказал, проверкой и установкой флага... нет, конечно бывают моменты, когда исключения используются для уведомления... например в тех же индейцах это сплошь и рядом... но когда таким образом осуществляется проверка на "живость" объекта... брр.. |
| Автор: ama_kid 31.5.2007, 12:56 |
| MetalFan Т.е. ты не видишь тут поля для утечек памяти, непроизвольного разрушения объекта или еще какой-нибудь катастрофы, а только то, что это непривычно а-ля "бр.."? Ну хоть это радует и я уже спокоен за свои проекты На мой взгляд, сознательно вызванное и корректно обработанное исключение гораздо лучше, чем наличие ненулевой вероятности того, что в процедуре, сбрасывающей флаг, может произойти необработанное исключение, повлекшее аварийный выход из этой процедуры с оставленным несброшенным флагом, ну и до кучи - необходимости держать ради каждой формы свои флаги... Тем более, видно, что часть в блоке try - в принципе не нужна при Action:=caFree; ибо заведомо будет исключение, это у меня оставлено только для личного удобства, однотипности и ради потакания привычке (ну и для случайного неиспользования Action:=caFree)... |
| Автор: aktuba 31.5.2007, 13:21 | ||
А на мой взгляд, программировать на основе эксепшенов не верно... Это все-равно, что создавать код и заранее знать что в нем ошибки, но продолжать поддерживать его в том же виде. Эксепшены должны быть для обработки не предвиденных ошибок, действий пользователей и т.д., но не для обработки действий программы! |
| Автор: MetalFan 31.5.2007, 16:09 | ||||||
не вижу СОЗНАТЕЛЬНОГО вызванного исключения. сознательное вызванное исключение имхо должно выглядеть так:
но никак попытка вызова метода из возможно уже разрушенного класса. тем более неизвестно где и когда там происходит нарушение доступа к памяти... а если по тому адресу уже что-то располагается?
в корректно написанной программистом процедуре не может происходить необработанных исключений. гораздо страшнее возникающее AV при вызове у "мертвой" формы ShowModal. |
| Автор: pseud 31.5.2007, 16:26 | ||||||
Полностью поддерживаю MetalFan и aktuba. Код выглядит нелепо. Добавлено через 4 минуты и 53 секунды так по-моему красивее и правильнее
|
| Автор: ama_kid 31.5.2007, 17:21 | ||
| Ну, это вообще не агрумент Мы вроде спорим не про то, как красивее - в конце концов, это индивидуальное дело каждого...
А вот с этим - можно и поспорить (а возможно узнать что-то новое)... Но: без оффтопа, переезжаем http://forum.vingrad.ru/forum/topic-154111/kw-создание-окна/view-all.html... |
| Автор: pseud 31.5.2007, 17:44 | ||||
это из твоей темы "Как вы создаете окна в приложении (runtime)? вспомогательные окна"
ama_kid, Работаю именно с объектами, не через сообщения, немножко там еще интерфесы использую для большей гибкости. Хочешь - могу в подробностях изложить. P.S. Насчет "нелепо" - извини. |