Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.01.15;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.026 c
14-1135024725
Piter
2005-12-19 23:38
2006.01.15
Ссылки на всякие "Разошли своим друзьям, иначе не будет счастья"


8-1123374084
shadowgoga
2005-08-07 04:21
2006.01.15
Проиграть wav-файл "по кругу".


2-1135582359
ksu
2005-12-26 10:32
2006.01.15
прозрачный фон TLabel


2-1135525506
lex85
2005-12-25 18:45
2006.01.15
DateTimePicker


3-1132305106
Anny
2005-11-18 12:11
2006.01.15
Прога считывания и обработки штрих кода...