Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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
2-1135696721
dera
2005-12-27 18:18
2006.01.15
Как добавить поле в таблицу с помощью SQL?


14-1134521031
за пиратство
2005-12-14 03:43
2006.01.15
Надо ли сажать в тюрьму за диски ? ( ГэБесия )


14-1135156039
dapher
2005-12-21 12:07
2006.01.15
Способы отбора данных


2-1135611497
kotbazilio
2005-12-26 18:38
2006.01.15
Удалить запись из таблицы


2-1135516567
azl
2005-12-25 16:16
2006.01.15
При пертаскивании формы не за заголовок не работает OnMouseUp





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский