Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
3-83929
AlexA
2003-05-30 12:06
2003.06.26
Как программным способом изменить ширину MEMO в FastReporte.


14-84541
race1
2003-06-07 08:32
2003.06.26
XP Style


8-84451
korepan
2003-03-12 15:02
2003.06.26
Народ, помогите с Opengl


1-84368
kasper
2003-06-16 17:34
2003.06.26
Помогите с выводом на печать!!


7-84798
Ал
2003-04-17 09:27
2003.06.26
Как сменить фон раб. стола (bmp), если включен ActiveDesktop?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский