Форум: "Потрепаться";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];
ВнизException в доп. потоке Найти похожие ветки
← →
Германн © (2005-12-18 03:09) [0]Тема навеяна некими сообщениями в форуме и моими измышлениями по сему поводу.
Имхо, exception в доп. потоке весьма неординарная проблема. Если я не прав, ткните меня носом в грязь! Если я прав, дайте пожалуйста ссылки на сей сабж. Меня интересуют, прежде всего, ссылки на ИНет ресурсы, но и ссылки на ХардКопи, то же приветствуются.
← →
iZEN © (2005-12-18 03:18) [1]Исключения оформляются в виде фреймов стека конкретного потока (thread).
Они независимы от других потоков (thread"s).
← →
Карелин Артем © (2005-12-18 08:44) [2]Try Except в потоке и никах проблем не наблюдается
← →
Sergey Masloff (2005-12-18 08:55) [3]Проблем с Exception в потоках нет за исключением того что обработано оно должно быть в том же потоке. Если нужно уведомить другой поток то гаси Exception внутри своего и сообщай второму любыми штатными средствами.
Это ж тривиально и в справке написано....
← →
Sergey Masloff (2005-12-18 10:56) [4]Handling exceptions in the thread function
это название топика в справке
← →
iZEN © (2005-12-18 17:47) [5]Дополню Sergey Masloff (18.12.05 08:55) [3].
Для передачи объекта исключения одного потока (треда) другому потоку (треду) в простейшем случае можно использовать вызов процедуры/функции потока-приёмника. Объект исключения передавать как параметр.
← →
Суслик © (2005-12-18 17:54) [6]
> процедуры/функции потока-приёмника
ну это тогда не передача, а просто вызов метода потока приемника. имхо.
я бы сделал так:
1. функцией AcquireExceptionObject получаешь объект.
2. средствами синхронизации делаешь raise данному объекту в потоке приемнике - тогда это настоящая передача. имхо.
типа того сделано в методе synchronization дабы передать исключение в данном методе (он то выполняется в контектсе главного потока) в вызывающий поток.
← →
Германн © (2005-12-19 02:23) [7]
> Sergey Masloff (18.12.05 08:55) [3]
>
> Проблем с Exception в потоках нет за исключением того что
> обработано оно должно быть в том же потоке. Если нужно уведомить
> другой поток то гаси Exception внутри своего и сообщай второму
> любыми штатными средствами.
> Это ж тривиально и в справке написано....
Да, наверно это тривиально. Может даже и в справке описано. Но вот так сходу найти трудно. Имхо.
Должен ли я понимать сей ответ так: если exception не обработано в том же потоке, в котором оно возникло и если автор программы никакими штатными средствами лично не сообщил об этом основному потоку, то сообщений об ошибке может не быть? Т.е. пользователь программы не получит сообщений об ошибке?
← →
Германн © (2005-12-19 02:25) [8]
> Sergey Masloff (18.12.05 10:56) [4]
>
> Handling exceptions in the thread function
> это название топика в справке
На вскидку попытался найти это в справке Д6. Не получилось. :(
Буду искать тщательнее.
← →
Суслик © (2005-12-19 11:09) [9]Германн.
Мое имхо - нафих справку (условно).
Смотри исходный код tthread. Для нахождения ответа на твое утверждение ружно порыться в:
1. TThread.Create
2. BeginThread
3. ThreadProc
Если отбросить линксовую составляющую (у меня д6, она там есть) всего не более 70 строк кода.
Отвечая на твой вопрос, что будет с исключением в доп потоке.
Ничего не будет. Оно как объект сохранится в свойстве TThread.FatalException. В событии OnTerminate класса TThread ты можешь воспользоваться свойством FatalException. Заметь, что OnTerminate вызывается в контексте главного потока. Поэтому внутри этого события ты можешь обработать FatalException и поднять исключение, которое дойдет до пользователя (поток то главный). Объект FatalException уничтожать не надо - он уничтожится в TThread.Destroy.
PS. Речь шла про d6.
← →
Суслик © (2005-12-19 11:53) [10]
> исключение, которое дойдет до пользователя (поток то главный)
В общем тут я не прав. :) Подзабыл уже.
Делай так
Посылай post сообщение клавному из OnTerminate и передавай параметры ошибки (текст). В обработчике генери исключение. Так точно будет работать.
← →
jack128 © (2005-12-19 12:52) [11]Германн © (19.12.05 2:23) [7]
если exception не обработано в том же потоке, в котором оно возникло и если автор программы никакими штатными средствами лично не сообщил об этом основному потоку, то сообщений об ошибке может не быть? Т.е. пользователь программы не получит сообщений об ошибке?
Не получит. А почему он должен получать какое то сообщение, если программист не удасужился это сообщение сгенерить??
Хотя нет. В том случае если необработанное исключение привело к завершению процесса, но есть стандарное сообщение ОС (типа "приложение выполнило недопустимую операцию" или что то в этом роде..
← →
BiN © (2005-12-19 13:03) [12]
> Суслик © (19.12.05 11:53) [10]
>
>
> > исключение, которое дойдет до пользователя (поток то главный)
>
> В общем тут я не прав. :) Подзабыл уже.
> Делай так
> Посылай post сообщение клавному из OnTerminate и передавай
> параметры ошибки (текст). В обработчике генери исключение.
> Так точно будет работать.
Не будет. Нельзя текст передавать post-сообщением, но 8 байт - можно.
← →
Суслик © (2005-12-19 13:53) [13]Ой ну ладно, полно есть способов передачи текста сообщениями в рамках одного приложения. Если в рамках разных приложений, то можно wm_copydata или самому через mapfiles реализовать.
Не принимается :)
← →
Leonid Troyanovsky © (2005-12-19 13:55) [14]
> Германн © (19.12.05 02:25) [8]
> > Handling exceptions in the thread function
> На вскидку попытался найти это в справке Д6. Не получилось.
http://community.borland.com/article/0,1410,10452,00.html
--
Regards, LVT.
← →
Leonid Troyanovsky © (2005-12-19 14:44) [15]
> Германн © (18.12.05 03:09)
> дайте пожалуйста ссылки на сей сабж. Меня интересуют, прежде
> всего, ссылки на ИНет ресурсы, но и ссылки на
Кста, вдогонку, еще один аспект, по поводу использования
"автоматической" переменной on E: Exception do .. см. также
http://www.rsdn.ru/Forum/Message.aspx?mid=883505&only=1
--
Regards, LVT.
← →
Суслик © (2005-12-19 15:02) [16]2Леонид.
А почему "Только показывать такие окна не надо" (это фраза из ссылки [15]).
По идее такое оно не должно никому помешать.
Если не прав, прошу объяснить в чем :)
Спасибо.
← →
Германн © (2005-12-19 15:56) [17]Спасибо всем.
← →
Leonid Troyanovsky © (2005-12-19 17:30) [18]
> Суслик © (19.12.05 15:02) [16]
> А почему "Только показывать такие окна не надо" (это фраза
> из ссылки [15]).
Ну, например, у этого потока нет TranslateMessage, что уже препятствует
привычной интерпретации юзеровского ввода.
Кроме того, окно, создаваемое AllocateHWND, все же, не предназначалось
для показа, и если уж его рисовать, то надежней собс-ручно (win32 API)
сделать его от начала до конца.
> По идее такое оно не должно никому помешать.
Возможно, но отсутствии всяких взаимодействий еще надо доказывать,
поэтому, я б его, вообще, сделал message only.
Рисовать же можно и в первичном потоке (да и удобней чем на API).
--
Regards, LVT.
← →
Leonid Troyanovsky © (2005-12-20 10:32) [19]
> Суслик © (19.12.05 15:02) [16]
> А почему "Только показывать такие окна не надо" (это фраза
> из ссылки [15]).
Тут некоторые коллеги задали похожий вопрос в почте,
поэтому решился дополнить предыдущие ответы.
Еще одна тонкость показа окон в доп. потоке в том, что перед
использованием, например, common controls (того же progress bar)
их библиотека должна инициализироваться в оном потоке.
Ну, и, опять же, для минимизации риска побочных эффектов,
лучше не использовать VCL, but WinAPI only.
Хотя, кое-что, сделать удается, см. например
http://groups.google.com/group/borland.public.delphi.nativeapi/msg/f392e4729c58ce8a
--
Regards, LVT.
← →
Суслик © (2005-12-20 11:39) [20]2Леонид.
Ну ясное дело, что winapi only. Никакого vcl.
Про common controls тоже понятно, т.к. вроде они по ole, а ole нужно инициализировать в потоке.
У меня после твоего ответа было ощущение, что есть еще какая-то тонкость. Ну не знаю какого характера. Например, что vcl где-то в недрах перебирает все видимые окна приложения и как-то с ними работает. Тем самым новое окно будет препятсвовать корректной рабоет vcl. :)
Правильно ли я понял, что если:
1. сделать окно на чистом api
2. родительским окном сделать дексктоп
3. есно сделать это корректно :)
то все будет ок?
← →
Игорь Шевченко © (2005-12-20 11:51) [21]
> т.к. вроде они по ole
Нет
← →
Leonid Troyanovsky © (2005-12-20 12:57) [22]
> Суслик © (20.12.05 11:39) [20]
> У меня после твоего ответа было ощущение, что есть еще какая-
> то тонкость. Ну не знаю какого характера. Например, что
> vcl где-то в недрах перебирает все видимые окна приложения
> и как-то с ними работает. Тем самым новое окно будет препятсвовать
> корректной рабоет vcl. :)
И случаи перебора бывают, например, DisableTaskWindows,
хотя, последнее относится к первичному потоку.
Т.е., в случае ShowModal окна вторичного потока не затрагиваются,
что уже само по себе не очень хорошо.
Ну, а о существовании других граблей могу лишь подозревать.
Т.е., каждое конкретное применение окна во вторичном потоке
надо изучать и обосновывать его корректность.
Пока же, IMHO, окна во вторичных потоках - вне генеральной
линии дельфи.
--
Regards, LVT.
← →
Leonid Troyanovsky © (2005-12-20 13:06) [23]
> Суслик © (20.12.05 11:39) [20]
> 1. сделать окно на чистом api
> 2. родительским окном сделать дексктоп
> 3. есно сделать это корректно :)
> то все будет ок?
В принципе - да.
Можно даже замахнуться на Application.Handle.
Однако, затем, видимо, придется работать напильником,
чтобы приложение в целом работало привычным образом.
Если б передо мной была поставлена подобная задача,
я б, наверное, попытался склонить чашу в сторону
двух отдельных приложений, взаимодействующих,
скажем, через OLE/COM & etc.
--
Regards, LVT.
← →
Суслик © (2005-12-20 14:06) [24]У меня тоже была такая идея - сделать отдельное приложение.
С передачей параметров (строк, например) проблем нет - да хоть тот же wm_copydata (пробовал, нормально работает).
Но есть еще вопросы, на решение которых просто сейчас нет времени.
Например, как сделать так, чтобы новое приложение не было видно в таскбаре. Понимаю, что вопрос скорее всего избит :)
Опять же - как сделать так, чтобы окно нового приложения было всегда НАД моим приложением (новое приложение я хотел бы использовать для отображения progress barов, дабы в основном приложении исключить использование Application.ProcessMessages).
Ну совет по поводу другого приложения я понял, спасибо.
← →
Alexander Panov © (2005-12-20 14:11) [25]Суслик © (20.12.05 11:39) [20]
Правильно ли я понял, что если:
1. сделать окно на чистом api
2. родительским окном сделать дексктоп
3. есно сделать это корректно :)
то все будет ок?
Все будет корректно не только для окна на WIN32API, но и для формы VCL.
Вся проблема в том, что для этой формы нужно полностью писать обработку сообщений. Но все равно плюс есть - внешний вид формы проектируется визуальными средствами.
← →
vuk © (2005-12-20 14:18) [26]>Вся проблема в том, что для этой формы нужно полностью писать
>обработку сообщений.
Проблема не в этом, а в том, что реализация форм в VCL такова, что код в базовых классах обращается к глобальным объектам типа Application, Screen и т.д.
← →
Leonid Troyanovsky © (2005-12-20 14:40) [27]
> Суслик © (20.12.05 14:06) [24]
> Опять же - как сделать так, чтобы окно нового приложения
> было всегда НАД моим приложением (новое приложение я хотел
> бы использовать для отображения progress barов, дабы в основном
> приложении исключить использование Application.ProcessMessages).
Для использования ProgressBar, IMHO, не нужен отдельный поток.
Изъян же ProcessMessages всего лишь в том, что неправильное его
использование приводит к возможности повторного входа в метод и т.п.
Поэтому, ProgressBar можно просто расположить на отдельной форме,
которую показать псвевдомодально, и которая, собс-но, будет
делать шаги (скажем, путем procedure NextStep: TNotifyEvent),
отображаемые в прогрессе.
--
Regards, LVT.
← →
Alexander Panov © (2005-12-20 14:56) [28]vuk © (20.12.05 14:18) [26]
Согласен... Но при известной осторожности все же можно использовать такой метод создания форм в отдельном потоке. Хотя я бы не стал рисковать...
← →
Суслик © (2005-12-20 15:12) [29]
> [27] Leonid Troyanovsky © (20.12.05 14:40)
> Поэтому, ProgressBar можно просто расположить на отдельной
> форме,
> которую показать псвевдомодально, и которая, собс-но, будет
> делать шаги (скажем, путем procedure NextStep: TNotifyEvent),
> отображаемые в прогрессе.
Под progress bar я имею в виду не только одноименный компонент, но и любое окно со схожей семантикой - информационное окно при долгой операции.
Если окно сделать в главном потоке и в главном же делать долгую операцию, то все равно нужно обрабатывать сообщения, иначе окно не будет перерисовано.
Поэтому либо:
1. Отдельный поток для окна
2. Отдельный поток для долгой операции (это в ложившейся системе сделать будет крайне непросто - система большая).
3. Отдельное приложение для окна.
П.п. 1 и 3 наиболее просты для реализации, исключая технические проблемы.
← →
vuk © (2005-12-20 15:24) [30]Для отображения прогресса длинной операции в потоке можно сделать отдеьное окно в основном потоке и передавать в него состояние операции в потоке через оконные сообщения.
← →
Leonid Troyanovsky © (2005-12-20 15:26) [31]
> Суслик © (20.12.05 15:12) [29]
> П.п. 1 и 3 наиболее просты для реализации, исключая технические
> проблемы.
Зато, 2 - самый верный, бо первичный поток, все же, для юзера.
Кста, не исключаю и 4 - отдельный процесс для длительной операции.
--
Regards, LVT.
← →
Суслик © (2005-12-20 15:41) [32]
> [30] vuk © (20.12.05 15:24)
Да можно. Но все равно нужно из длинной операции явно обрабатывать сообщения, например, вызывая Application.ProcessMessages.
← →
vuk © (2005-12-20 15:42) [33]>Application.ProcessMessages.
На кой?
Страницы: 1 вся ветка
Форум: "Потрепаться";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.012 c