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

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

Отловить ошибку в TThread [D7, WinXP]


Страницы:   1 2 3

Alex_C ©   (2007-08-09 13:26:00) 

Проблема: получаю данные из инета в отдельном потоке, чтоб не тормозить программу и отсылаю их в основную прогу. А вот если пользователь закрывает программу во время приема данных вылетает ошибка доступа - тут как бы все понятно - программы в памяти уже нет, а прием данных все продолжается и происходит обращение в никуда. Как этого избежать, кроме как не закрывать прогу до завершения приема данных? Пробовал в потоке ставить try... except - не помогает.
Прием данных осуществляю ф-цией InternetReadFile.


Leonid Troyanovsky   (2007-08-10 12:49:00) [21]


> oxffff ©   (10.08.07 12:35) [19]

> Можете считать это анонимным методом.

Не нужно никаких анонимных методов, а нужен обычный метод формы.
И не потребуется нелепых приседаний с TMethod и позорных form1.

> Правильно и заплакали потому, что до SyncList по другому
> не добраться.

Незнающим как синхронизироваться с главным потоком
надо пользовать TThread instead CreateThread

> У вас будет более 3 секунд для гарантии того, что все потоки
> завершатся.

Cначала у нас была вечность. Так что ж смутило?
Ремарка в msdn относится не к этому параметру.

> 100 раз подумайте. А потом промолчите. Быть может вы не

Может и не прав. А молчать невежливо, если спрашивают.

--
Regards, LVT.


MetalFan   (2007-08-10 12:45:00) [22]

может стоит BeginThread вместо CreateThread использовать?!
да и приведенный пример слишком сложен для понимания человеку, который ранее не столь глубоко знаком с потоками...


oxffff   (2007-08-10 12:35:00) [23]

To Leonid Troyanovsky ©  
Странно слышать от мастера.
Сейчас я вам повышу вашу квалификацию

А что вы не знаете как передаются параметры при register calling convention?
Напоминаю EAX, EDX, ECX и далее stack.

procedure PendingCallInMainThread(Self:pointer);
Можете даже так реализовать.
procedure PendingCallInMainThread;

Можете считать это анонимным методом.

>За form1. - убивать из рогатки.

За form1 в PendingCallInMainThread я так понимаю?

PendingCallInMainThread использовался как метод демострация того, что поток работает.

>А Thread.Synchronize(nil,TThreadMethod(Method)) - растрогал до слез.

Правильно и заплакали потому, что до SyncList по другому не добраться.

>И ты полагаешь, что замена -1 на 5000
>сделает ее поведение более определенным?

У вас будет более 3 секунд для гарантии того, что все потоки завершатся.
В данном конкретном примере проблем не будет. Что то опять незачет.

>Да, ну невозможно такое всерьез обсуждать.
>Псевдоглубокомысленная малограмотность.

Вы хоть поняли, что сами сказали?

В следующий раз давая кому-либо или чему-либо характеристику 100 раз подумайте. А потом промолчите. Быть может вы не правы.

>Да, ну невозможно такое всерьез обсуждать.
>Псевдоглубокомысленная малограмотность.

Сами хоть поняли, что сказали.


Leonid Troyanovsky   (2007-08-10 12:02:00) [24]


> oxffff ©   (10.08.07 11:11) [16]

procedure PendingCallInMainThread(Self:pointer);
Method.code:=@PendingCallInMainThread;

На деструктор сил хватило, а метод формы влом?
За form1. - убивать из рогатки.
А Thread.Synchronize(nil,TThreadMethod(Method)) - растрогал до слез.

Да, ну невозможно такое всерьез обсуждать.
Псевдоглубокомысленная малограмотность.

> Модифицируй  WaitForMultipleObjects  на
> WaitForMultipleObjects(Length(Threads),@Threads,TRUE, 5000)

И ты полагаешь, что замена -1 на 5000
сделает ее поведение более определенным?

--
Regards, LVT.


oxffff   (2007-08-10 11:14:00) [25]

Сформулирую точнее.

Что конкретно вынуждает вас давать характеристику "бред"?


oxffff   (2007-08-10 11:11:00) [26]


> Leonid Troyanovsky ©   (10.08.07 11:07) [15]
>
> > oxffff ©   (10.08.07 10:54) [14]
>
> > > Мысль: пример неясный.
>
> > Вам? :)
>
> По мне там, вообще, бред.
> Из разряда сверхценных идей.
>
> --
> Regards, LVT.


Что конкретно вас не устраивает в коде?


Leonid Troyanovsky   (2007-08-10 11:07:00) [27]


> oxffff ©   (10.08.07 10:54) [14]

> > Мысль: пример неясный.

> Вам? :)

По мне там, вообще, бред.
Из разряда сверхценных идей.

--
Regards, LVT.


oxffff   (2007-08-10 10:54:00) [28]


> Мысль: пример неясный.


Вам? :)


Leonid Troyanovsky   (2007-08-10 10:47:00) [29]


> oxffff ©   (10.08.07 09:27) [12]

> Поясните, свою мысль

Мысль: пример неясный.

--
Regards, LVT.


oxffff   (2007-08-10 09:27:00) [30]


> Leonid Troyanovsky ©   (10.08.07 09:16) [11]
>
> > oxffff ©   (09.08.07 23:14) [9]
>
> > Вот тебе пример
>
> Ночь в Крыму - все в дыму, и пушки стреляют.
>
> --
> Regards, LVT.


Поясните, свою мысль


Leonid Troyanovsky   (2007-08-10 09:16:00) [31]


> oxffff ©   (09.08.07 23:14) [9]

> Вот тебе пример

Ночь в Крыму - все в дыму, и пушки стреляют.

--
Regards, LVT.


oxffff   (2007-08-09 23:36:00) [32]

Из-за особенности работы функции,

If one of these handles is closed while the wait is still pending, the function's behavior is undefined.

Модифицируй  WaitForMultipleObjects  на

WaitForMultipleObjects(Length(Threads),@Threads,TRUE, 5000)


oxffff   (2007-08-09 23:14:00) [33]

Вот тебе пример для запуска +63 потока. При закрытии приложении ждет завершения всех 63 дополнительных потоков и выводит сообщение.

ThreadParams=packed record
Sync:Thandle;
end;

PThreadParams=^ThreadParams;

 TForm1 = class(TForm)
   Memo1: TMemo;
   procedure FormClose(Sender: TObject; var Action: TCloseAction);
 private
   { Private declarations }
 protected
 params:ThreadParams;
 public
   { Public declarations }
 Threads:array[0..MAXIMUM_WAIT_OBJECTS-2] of THandle;
 constructor Create(AOwner: TComponent);override;
 destructor destroy;override;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure PendingCallInMainThread(Self:pointer);
begin
form1.Memo1.Lines.add('Ðàáîòàåò ïîòîê ');
end;

function ThreadProc(const params):DWORD;stdcall;
var Method:TMethod;
begin
Method.data:=nil;
Method.code:=@PendingCallInMainThread;
while WaitForSingleObject(ThreadParams(params).Sync,0)WAIT_OBJECT_0 do
 begin
 TThread.Synchronize(nil,TThreadMethod(Method));
 sleep(1000);
 end;
end;

{ TForm1 }

constructor TForm1.Create(AOwner: TComponent);
var i:integer;
   tid:DWORD;
begin
inherited;
params.Sync:=CreateEvent(nil,TRUE,FALSE,nil);
if params.SyncINVALID_HANDLE_VALUE then
   begin
   for i:=low(Threads) to High(Threads) do Threads[i]:= CreateThread(nil,0,@ThreadProc,@params,0,tid);
   end;
end;

destructor TForm1.destroy;
begin
inherited;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
SetEvent(params.Sync);
case WaitForMultipleObjects(Length(Threads),@Threads,TRUE, INFINITE) of
WAIT_OBJECT_0: Showmessage(Все дополнительные потоки завершены');
else //
end;
end;


Alex_C   (2007-08-09 19:25:00) [34]

То oxffff: гм, только сейчас сообразил, что ошибка вылетает на новой многопроцессорной машине! На обычных пнях 4 ее нет! Выходит надо менять реализацию Terminate ? А как?


Alex_C   (2007-08-09 19:14:00) [35]

Да для Сергей М.: ошибка такая: Ошибка доступа к user.dll - по моему так пишет. Могу ошибаться.


Alex_C   (2007-08-09 19:13:00) [36]

Спасибо за советы ребята! Буду пробовать!


oxffff   (2007-08-09 13:55:00) [37]


> не срабовать


Не сработать


oxffff   (2007-08-09 13:54:00) [38]


> tesseract ©   (09.08.07 13:29) [1]
> при выходе из программы вызови TThread.WaitFor. Напиши нормальный
> обработчик terminate - т.е реализуй хотя бы базовый уровень
> контроля потоков.


В MSDN есть раздел Synchronization and Multiprocessor Issues.
Текущая реализация

procedure TThread.Terminate;
begin
 FTerminated := True;
end;

Может не срабовать на многопроцессорной машине, если предположить, что эти потоки выполняются на разных процессорах.
Второй процессор может не обновить кэш. И попытаться отослать данные.

Так что реализацию Thread нужно поменять.

Для автора темы. Используй Event или Interlockedxxx для гарантии


Сергей М.   (2007-08-09 13:34:00) [39]


> вылетает ошибка доступа


И все ?!

Прямо так вылетая и говорит, мол, ошибка доступа, а больше, мол, ничего не скажу ?

Вот уж не поверю)

А ведь это крайне важно для поиска "неисправности" !


Loginov Dmitry   (2007-08-09 13:33:00) [40]

Если крайне полезная функция:
TerminateProcess($FFFFFFFF, 0);
Панацея ото всех бед :))


Страницы:   1 2 3

Наверх

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