Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

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;


Наверх

Титульная страница Поиск, карта сайта Написать письмо