![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
raise в потоке
TUser © (2004-08-10 13:31:00)Если raise вызываем в потоке, то окно с сообщением об ошибке не появляется, а просто завершается выполнение потока, выполняется OnTerminate. А можно ли сделать так, чтобы показать нормальное окно с сообщением об ошибке. Можно, конечно, сделать так
try
... raise ...
except
FTemp:='Error message';
Synchronize (Er);
raise Exception.Create(''); // terminating thread
end;
procedure TMyThread.Er;
begin
ShowMessage(FTemp+#13'Thread terminated');
end;
Как это сделать правильно?
jack128 (2004-08-10 17:58:00) [1]Глянь как сделано в SConnect.TTransportThread.Execute
Бином Ньютоныч (2004-08-10 17:53:00) [2]>Skyle © (10.08.04 14:07) [5]
Остается только добавить, что это поведение полностью соответствует идеалогии Windows в данном вопросе:)
y-soft (2004-08-10 17:16:00) [3]Вот офицальный ответ Borland по subj:
http://community.borland.com/article/0,1410,10452,00.html
И некторые отличия для D6 и старше:
http://bdn.borland.com/article/0,1410,27655,00.html
Skyle (2004-08-10 14:10:00) [4]
> Функция SysUtils.ThreadWrapper
Пардон, конечно System.ThreadWrapper...
Skyle (2004-08-10 14:07:00) [5]Я тут сейчас покопался в коде (Delphi5) и нарыл следующее.
В конструкторе TThread вызывается функция BeginThread, в которую передаётся в параметре ThreadFunc адрес функции Classes.ThreadProc. Назначение ThreadProc - вызвать метод Execute нужного TThread. В функции BeginThread вызывается функция создания апишного Thread CreateThread, которой в качестве параметра ThreadFunc передаётся не тот Classes.ThreadProc, а некоторая System.ThreadWrapper.
Адрес функции Classes.ThreadProc содержится как параметр записи, передаваемой API функции в 4-м параметре.
Функция SysUtils.ThreadWrapper вызывает эту самую Classes.ThreadFunc и в случае чего гасит исключения (потому что складывает в стек адрес функции System._ExceptionHandler, которая не оставляет от исключения ничего.
Следовательно, либо исключение ловиться в Execute, либо не ловиться нигде.
В общих чертах я понял так.
С удовольствием приму поправки.
y-soft (2004-08-10 14:03:00) [6]
try
while not Terminated do
//raise MyException.Create('Test');
except
On E:Exception do
begin
E.Message := Format('Ошибка в потоке обработки:'#13#10#13#10' %s',[E.Message]);
Application.ShowException(E);
//или Application.HandleException(E);
end;
end;
inic (2004-08-10 13:55:00) [7]А что если все оставить как у тебя, только убрать из except..end
строку "raise Exception.Create(''); //..."
TUser (2004-08-10 13:39:00) [8]Хм. Хочу вообще избежать 're-raising' и try...except. Т.е. так - если вызывался raise, то окошко - и поток завершается.
inic (2004-08-10 13:36:00) [9]Попробуй так:
try
... raise ...
except
FTemp:='Error message';
Synchronize (Er);
end;
procedure TMyThread.Er;
begin
raise Exception.Create(FTemp); // terminating threadend;
end;