Форум: "Основная";
Текущий архив: 2003.06.26;
Скачать: [xml.tar.bz2];
ВнизTThread Найти похожие ветки
← →
Alibaba (2003-06-10 13:24) [0]Всем привет.
Не знаю в каком разделе разместить вопрос о потоках, поэтому спрошу в основном разделе.
Если я не прав - модератор меня поправит.
Ситуация:
В главной программе создается дополнительный поток
type
TDepend = class(TThread)
var
Depend: TDepend;
Задача потока: выполнять SQL-запросы
procedure TDepend.Execute;
begin
try
qr.Prepare;
qr.Open;
except
on E: Exception do
ShowMessage(Format("%s: %s", [E.ClassName, E.Message]));
end;
end;
Все работает супер, но...
Если SQL-запрос синтаксически неверный, например:
"select * "
1. В Design Mode, когда я внутри оболочки Delphi пошагово выполняю программу - Exception отрабатывается.
2. В Run Time, когда я запускаю откомпилированный EXE-файл - Exception НЕ отрабатывается. ПОЧЕМУ?
Подскажите, плиз, уважаемые Мастера.
← →
HolyGlory (2003-06-10 13:31) [1]А кусок кода по-больше кинуть можешь?
← →
Alibaba (2003-06-10 13:34) [2]> HolyGlory
Мне не жалко. Но зачем?
Если есть конкретный вопрос - задавай.
← →
Digitman (2003-06-10 13:36) [3]
> В Run Time, когда я запускаю откомпилированный EXE-файл
> - Exception НЕ отрабатывается.
ничего подобного ! оч даже "отрабатывается" !
← →
Alibaba (2003-06-10 14:10) [4]>Digitman
Понимаеш, какое дело...
Он действительно иногда отрабатывает, иногда - нет.
Я не могу понять почему.
Если обрыв сети - отрабатывается Exception.
А если неверный SQL-запрос - программа молча что-то делает и нечего не сообщает.
← →
Digitman (2003-06-10 14:23) [5]да ну не говори ерунды-то !)
все прекрасно отрабатывается ! поставь брейкпойнт на on E: Exception do..., сэмулируй различные искл.ситуации и убедись сам, "поймав" этот брейкпойнт)
а вот дальше - чудеса у тебя начнутся !)
ShowMessage() запросто сам вызовет исключение (необрабатываемое тобой, что совершенно недопустимо !), ибо в этом код.потоке вызываешь ты поточно-небезопасную процедуру !
во многих случаях ты даже диал.окна со своим сообщением об ошибке не увидишь (очевидно, именно его ты ожидаешь увидеть как факт возникшего исключения)
← →
Zemal (2003-06-10 14:51) [6]Digitman >> Послушайте, сударь, а зачем собственно сообщения из потока выводить? Поток должен работать, а не диалоги с пользователем водить. Хочешь выдать сообщение - пошли форме message, а там из главного кодового потока (как часто поток VCL называют) выводи всякие "Шоу" и "Мессаги" :).
Кстати, если у потока нет владельца, то все "эксцепшены" уйдут в никуда! Теперь понятно почему в конструкторе нужно Self, а не Nil указывать?! Поток все эксцепшены передаёт родителю, если он есть, а если нет, то тю-тю :))
← →
Alibaba (2003-06-10 14:55) [7]
> Digitman
> поставь брейкпойнт на on E: Exception do..., сэмулируй
> различные искл.ситуации и убедись сам, "поймав" этот
> брейкпойнт
Ты это конечно читал: Alibaba © (10.06.03 13:24)
1. В Design Mode, когда я внутри оболочки Delphi пошагово выполняю программу - Exception отрабатывается.
А можно поподробнее. Почему я
во многих случаях даже диал.окна со своим сообщением об ошибке не увидишь
← →
Alibaba (2003-06-10 14:59) [8]>Zemal
По поводу в конструкторе необходимо Self указывать.
Может быть у меня не правильно построен конструктор?
constructor TDepend.Create;
begin
ss:=TSession.Create(Application);
db:=TDatabase.Create(Application);
qr:=TQuery.Create(Application);
inherited Create(False);
end;
← →
Digitman (2003-06-10 15:01) [9]
> Zemal
> зачем собственно сообщения из потока выводить
какие ко мне претензии-то ?) не я их "вывожу" - автор вопроса зачем-то это делает, не монимая, что это как минимум не потокобезопасно !
> если у потока нет владельца, то все "эксцепшены" уйдут в
> никуда!
у код.потока нет владельца.
если не считать в кач-ве такового процесс, в контексте которого код.поток стартован и работает.
и причем здесь "владелец" и системная обработка искл.ситуаций в код.потоках ? абсолютно несвязанные вещи)
> Теперь понятно почему в конструкторе нужно Self,
> а не Nil указывать?!
Никакой разницы. С обработкой исключений в поточной ф-ции это никак не связано.
>Поток все эксцепшены передаёт родителю,
> если он есть, а если нет, то тю-тю :))
Еще раз - нет у потока никакого "родителя". И "владельца" тоже нет. Кроме процесса как ОС-объекта.
И не "тю-тю", а - непредсказуемые последствия, вплоть до краха процесса, ожидают программу в случае необработки потенциально возникающих исключений в код.потоке
← →
Zemal (2003-06-10 15:10) [10]Ах, да! Я совсем забыл, что в стандартном TThread"е не указывается владелец... :(( Он по умолчанию Self... а может и нет... нужно лезть в исходники и смотреть...
Просто я не пользуюсь этим классом, т.к. он отстойный и не предоставляет приемлемых средств управления потоками (особенно тяжело с синхронизацией). Мой совет: используй какую-нибудь библиотеку, например Gala. Там реализовано всё, семафоры, мьютексы и т.д. и т.п. Решены проблемы синхронизации. Могу прислать, кому надо. Кстати, всё написано без использования классов Делфи, т.е. построено от TObject. Кому надо - мыльте.
← →
Alibaba (2003-06-10 15:11) [11]Чем скромнее жесты -
Тем глубже смысл.
Из всего размахивания руками Digitman-а я понял, что необходимо при обработке исключения вызывать не ShowMessage, а сообщать об этом основному потоку двумя известными мне способами:
1. Synchronize
2. SendMessage
← →
Digitman (2003-06-10 15:11) [12]
> Alibaba
> А можно поподробнее. Почему я
>
> во многих случаях даже диал.окна со своим сообщением об
> ошибке не увидишь
потому что "внутри" ShowMessage() создается и визуализируется диалоговая форма. Форма есть VCL-объект, причем - не потокобезопасый. Обращение ко всем потоконебезопасным VCL-объектам следует синхронизировать с осн.потоком процесса.
бъюсь об заклад, что попытка асинхронногго вызова в твоем кодовом потоке проц-ры ShowMessage() вызывает исключение с диагностикой "Canvas does not allow drawing", которое ты не перехватываешь и игнорируешь, "выпуская" за пределы поточной ф-ции, что совершенно недопустимо.
Иными словами, либо веди лог исключений иными средствами (например, запись в монопольно открытый файл) либо синхронизируй вызов ShowMessage() с осн.потоком процесса VCL-приложения
← →
Digitman (2003-06-10 15:16) [13]
> Alibaba
А ты однако хам, сударь !
Вчитайся в мой пост Digitman © (10.06.03 14:23) !
Я тебе сразу сказал, с какого места следует тебе в отладочном пошаговом режиме искать свои "глюки" ! Ты же продолжаешь "крутить головой" в сторону абсолютно не имеющих отношения к сабжу "подсказок" а-ля "владелец", "родитель" и пр.
← →
Zemal (2003-06-10 15:20) [14]Digitman >> Ладно-ладно :), не дуйся :). Я давно не держал в руках TThread :). Щас залез в исходники и увидел что, делфийные потоки - отстой, имеют свой хэндл и умеют только месаги объекту Application слать. Короче никакого контроля над потоками Делфи нет :(. Зависнет поток в своём цикле и не определишь что с ним... только если ручками... но ручками долго, нудно и коряво :(. Честное слово, легче на API поток организовать, чем заставить хорошо работать Делфийный Thread.
← →
Alibaba (2003-06-10 15:26) [15]>Digitman
Нет я не хам. Не хотел никому нахамить.
Ну ты же не будеш спорить с тем что ты размахиваеш руками, вместо того, что бы просто указать на ошибку.
Хотя... просто обьяснить - это исскуство мастеров.
Не всем под силу.
За ответ и помощь - ОГРОМНОЕ СПАСИБО.
← →
Digitman (2003-06-10 15:27) [16]
> Zemal
не возражаю)... на вкус и цвет, как говорится,....
скажу лишь что в своей частной практике я никогда не встречал никаких проблем со классом TThread)... ни с его функциональностью ни с корректностью реализации)
← →
Zemal (2003-06-10 15:28) [17]Кстати, ошибки, возникающие в потоке не обрабатываются приложением, т.к. оно ничего не знает о деятельности потока. Если поток наткнулся на ошибку, то он шлёт приложению сообщение WM_ERRORMESSAGE (если не запамятовал). Значит поток разрушается от критической ошибки и поэтому окно Application ничего о ней незнает... вот такая вот ботва, блин :(.
← →
Digitman (2003-06-10 15:30) [18]
> Alibaba
Еще раз повторяю - я тебе абсолютно точно указал ключевой момент ошибки !) ... а уж как его обойти - это твои проблемы) ... способов - море ! Я что, должен тебе их все перечислять ?)
← →
Alibaba (2003-06-10 15:36) [19]>Digitman
Я же не поленился: Alibaba © (10.06.03 15:11)
← →
Zemal (2003-06-10 15:37) [20]Весь контроль над потоком должен брать на себя программист, т.е. реализовывать обмен сообщениями. А в потоке сплошняком должно стоять try...exception/finaly. Вся обработка ошибок должна быть реализована ручками, например при I/O - if IOResult = 0... и т.д.
Если поток построен иначе, то такое приложение работать никогда хорошо небудет... вечно будут глюки.
Поэтому я предпочитаю стороние потоки, в которых реализовано что-то типа "центра управления потоками". Смешно даже говорить как летали бы самолёты-потоки без "центра управления" или хотя бы диспетчерской. В таком случае в Делфи удачно может "летать" только один поток :)).
← →
Digitman (2003-06-10 15:47) [21]
> Alibaba
ну и молодца !)
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.06.26;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.047 c