powered by simpleCommunicator - 2.0.37     © 2025 Programmizd 02
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
25 сообщений из 48, страница 1 из 2
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093498
BorodaOleg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго дня!

Собственно, имеется программа (писал не я, только дорабатываю). В ней есть 4 потока (вообще их там больше, но для проведения эксперимента достаточно и их). Метод execute реализован следующим образом:
procedure CL4Module.Execute;
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
var StrMsg  : string;
    i : Integer; b : Byte;
Begin
    FDEFINE(BOX_L4,BOX_L4_SZ,True);
   while not Terminated do Begin
     FGET(BOX_L4,@m_nMsg);
     if Terminated then Exit;
     if m_nL4Synchronize = 1  then Synchronize(OnHandler)
     else EventHandler(m_nMsg);
   End;
End;


Содержимое FDEFINE
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
procedure FDEFINE(nIndex:Integer;w_lBoxSize:DWord;blSynch:Boolean);
Begin
  try
    with pHiBuff[nIndex] do begin
      if sCS=Nil then Begin
        sCS         := TCriticalSection.Create;
        SetLength(pb_mBoxCont,w_lBoxSize+3000);
        w_mEvent    := CreateEvent(nil, False, False, nil);
        w_mBoxSize  := w_lBoxSize;
        w_mBoxCSize := w_lBoxSize;
        w_mBoxWrite := 0;
        w_mBoxRead  := 0;
        w_mBoxMesCt := 0;
        w_blSynchro := blSynch;
        m_byIsEvent := False;
        ResetEvent(w_mEvent);
      end;
    end;
  except
     SClass.ToStringBox(ET_CRITICAL, 'Ошибка в utlbox.FDEFINE ');
  end;
End;


Содержимое FGET
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
function FGET(nIndex:Integer;pb_lInBox:Pointer):Integer;
Var wLng:Word;
Begin
  try
    if pHiBuff[nIndex].w_blSynchro then WaitForSingleObject(pHiBuff[nIndex].w_mEvent, INFINITE);
     Move(pHiBuff[nIndex].pb_mBoxCont[pHiBuff[nIndex].w_mBoxRead],wLng,2);
     Move(pHiBuff[nIndex].pb_mBoxCont[pHiBuff[nIndex].w_mBoxRead],pb_lInBox^,wLng);
     pHiBuff[nIndex].w_mBoxRead  := pHiBuff[nIndex].w_mBoxRead + wLng;
     pHiBuff[nIndex].w_mBoxSize  := pHiBuff[nIndex].w_mBoxSize + wLng;
     pHiBuff[nIndex].w_mBoxMesCt := pHiBuff[nIndex].w_mBoxMesCt - 1;
     if(pHiBuff[nIndex].w_mBoxRead > pHiBuff[nIndex].w_mBoxCSize) then pHiBuff[nIndex].w_mBoxRead := 0;
     if pHiBuff[nIndex].w_mBoxMesCt=0 then ResetEvent(pHiBuff[nIndex].w_mEvent)
     else SetEvent(pHiBuff[nIndex].w_mEvent);
     result := wLng;
  except
    SClass.ToStringBox(ET_CRITICAL, Ошибка в utlbox.FGET ');
  end;
End;


Содержимое Destroy
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
destructor CThread.Destroy;
begin
  try
  if Suspended then begin
    TerminateThread(Self.Handle, 0);
  end;
  except
    on E : Exception do
      SendEventBox(ETA_ERROR_METR+usedColor, 'Ошибка в : CThread.Destroy: '+E.Message);
  end;
  if SenderClass <> Nil then FreeAndNil(SenderClass);
  inherited;
end;


Вызов уничтожения потока из тела основной программы:
Код: pascal
1.
2.
3.
4.
5.
//  pL4Module.Suspend;
  pL4Module.Terminate;
//  FDEFINE(BOX_L4,BOX_L4_SZ,True);
//  FPUT(BOX_L4,@m_nMsg);
  if pL4Module <> nil then FreeAndNil(pL4Module);


Процедуры FPUT и FGET служат для передачи событий между модулями. В FGET ожидание события сформировано на базе WaitForSingleObject.
При вызове pL4Module.Terminate не происходит вообще ничего, pL4Module не обнуляется. При вызове FreeAndNil(pL4Module) вызывается Destroy. Если бы была открыта строка pL4Module.Suspend (как сейчас реализовано в проекте), то поток добросовестно убивается. Но это, насколько я понимаю, не верно.
Если не вызывать Suspend, то программа попадает в destructor TThread.Destroy модуля classes, затем в WaitFor и начинает крутится в бесконечном цикле внутри TThread.WaitFor со значением WaitResult = 258.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    repeat
      { This prevents a potential deadlock if the background thread
        does a SendMessage to the foreground thread }
      if WaitResult = WAIT_OBJECT_0 + 2 then
        PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);
      WaitResult := MsgWaitForMultipleObjects(2, H, False, 1000, QS_SENDMESSAGE);
      CheckThreadError(WaitResult <> WAIT_FAILED);
      if WaitResult = WAIT_OBJECT_0 + 1 then
        CheckSynchronize;
    until WaitResult = WAIT_OBJECT_0;


И я в упор не представляю, что может быть не верно... Может кто подскажет, или хотя бы на мысль наведет?
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093509
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BorodaOleg
постоянно крутится в процедуре TThread.WaitFor

Потому, что функция FGET висит - видимо, события ждёт, вечно.

BorodaOleg
Код: pascal
1.
2.
3.
if Suspended then begin
    TerminateThread(Self.Handle, 0);
  end;


В печь. Писателю - осиновый кол в сердце.

BorodaOleg
Вызов уничтожения потока из тела основной программы:
Код: pascal
1.
2.
3.
4.
5.
//  pL4Module.Suspend;
  pL4Module.Terminate;
//  FDEFINE(BOX_L4,BOX_L4_SZ,True);
//  FPUT(BOX_L4,@m_nMsg);
  if pL4Module <> nil then FreeAndNil(pL4Module);


В печь.
Заменить на
Код: pascal
1.
FreeAndNil(pL4Module);
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093510
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BorodaOleg
При вызове pL4Module.Terminate не происходит вообще ничего
Ошибаетесь. Происходит установка Terminated = True
BorodaOleg
pL4Module не обнуляется.
А должен? Серьезно?
BorodaOleg
Если бы была открыта строка pL4Module.Suspend (как сейчас реализовано в проекте), то поток добросовестно убивается
Нет. Поток брутально уничтожается. Потому, что вызовом Suspend (который вызывать для чужого потока запрещено, если вы не отладчик), а потом в деструкторе для усыпленного потока вызывается TerminateThread
BorodaOleg
Код: pascal
1.
2.
3.
  if Suspended then begin
    TerminateThread(Self.Handle, 0);
  end;

который вызывать вообще нельзя
BorodaOleg
Если не вызывать Suspend, то программа попадает в destructor TThread.Destroy модуля classes, затем в WaitFor и начинает крутится в бесконечном цикле внутри
Правильно. Потому что поток у вас находится в состоянии ожидания
BorodaOleg
Код: pascal
1.
 if pHiBuff[nIndex].w_blSynchro then WaitForSingleObject(pHiBuff[nIndex].w_mEvent, INFINITE);

и оттуда вы его не вывели.

Что нужно сделать:
1. Завести второй объект TerminateEvent и ждать в FGET двух хендлов. Если у вас все потоки останавливаются одновременно, то достаточно одного глобального события без автосброса. Если потоки останавливаются выборочно, то каждому потоку нужен свой объект
2. Написать адекватный деструктор потока
Код: pascal
1.
2.
3.
4.
5.
6.
destructor CThread.Destroy;
begin
  SetEvent(TerminateEvent)
  FreeAndNil(SenderClass);
  inherited Destroy;
end;


3. Весь код уничтожения потока сократить до одной строчки
Код: pascal
1.
FreeAndNil(pL4Module);


4. По завершению потока не забыть вызвать
Код: pascal
1.
CloseHandle(w_mEvent)


5. Строка
Код: pascal
1.
ResetEvent(w_mEvent);

лишняя
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093520
BorodaOleg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
BorodaOleg
Если не вызывать Suspend, то программа попадает в destructor TThread.Destroy модуля classes, затем в WaitFor и начинает крутится в бесконечном цикле внутри
Правильно. Потому что поток у вас находится в состоянии ожидания
BorodaOleg
Код: pascal
1.
 if pHiBuff[nIndex].w_blSynchro then WaitForSingleObject(pHiBuff[nIndex].w_mEvent, INFINITE);

и оттуда вы его не вывели.

Что нужно сделать:
1. Завести второй объект TerminateEvent и ждать в FGET двух хендлов. Если у вас все потоки останавливаются одновременно, то достаточно одного глобального события без автосброса. Если потоки останавливаются выборочно, то каждому потоку нужен свой объект
2. Написать адекватный деструктор потока
[src delphi]
destructor CThread.Destroy;
begin
SetEvent(TerminateEvent)
FreeAndNil(SenderClass);
inherited Destroy;
end;

Было у меня подозрение, что проблема кроется именно в том, что поток крутится в WaitForSingleObject(pHiBuff[nIndex].w_mEvent, INFINITE), вот только не знаю как его оттуда вывести. Пытался кинуть в него сообщение (FPUT(BOX_L4,@m_nMsg)) но эффекта не дало.
Вы предлагаете "Завести второй объект TerminateEvent и ждать в FGET двух хендлов", если честно, не совсем соображаю как. WaitForSingleObject, насколько я понимаю позволяет использовать только 1 event или я не прав? А если WaitForSingleObject зациклится на pHiBuff[nIndex].w_mEvent то как запустить ожидание 2-го handle?
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093523
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BorodaOleg
WaitForSingleObject, насколько я понимаю позволяет использовать только 1 event
Да. Но есть еще WaitForMultipleObjects
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093527
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кто мешает вместо INFINITE указать 100 и дальше ожидать в бесконечном цикле (колхоз конечно, но работать будет):
Код: pascal
1.
2.
3.
4.
5.
6.
7.
while True do
begin
  if WaitForSingleObject(pHiBuff[nIndex].w_mEvent, 100) = WAIT_OBJECT_0 then
    Break
  else if Terminated then 
    Exit;
end;



В функцию FGET необходимо передавать объект потока, чтобы была возможность контролировать свойство Terminated. Пример такой передачи по ссылке (см. функцию ThreadWaitTimeout и доп. класс TThreadAccessTerminated). Это на случай, если функция FGET реализована в другом модуле.
Либо сделать функцию FGET методом класса CThread
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093625
BorodaOleg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попытался сделать на WaitForMultipleObjects:
Конструктор Create
Код: pascal
1.
2.
3.
4.
5.
6.
constructor CThread.Create(Bool: boolean);
begin
  inherited Create(Bool);
  . . .
  TerminateEvent := CreateEvent(nil, True, False, 'TerminateEvent');
end;


Деструктор Destroy
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
destructor CThread.Destroy;
begin
  try
{  if Suspended then begin
    TerminateThread(Self.Handle, 0);
  end;}
  SetEvent(TerminateEvent);
  except
    on E : Exception do
      SendEventBox(ETA_ERROR_METR+usedColor, 'Ошибка в : CThread.Destroy: '+E.Message);
  end;
  FreeAndNil(SenderClass);
  inherited;
end;


Функция FGETMULT
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
function FGETMULT(nIndex:Integer; pb_lInBox:Pointer; AE: ArrayEvents):Integer;
Var wLng:Word;
Begin
  try
    case WaitForMultipleObjects(2, @AE, False, 1) of
      WAIT_OBJECT_0:
        begin
          Move(pHiBuff[nIndex].pb_mBoxCont[pHiBuff[nIndex].w_mBoxRead],wLng,2);
          Move(pHiBuff[nIndex].pb_mBoxCont[pHiBuff[nIndex].w_mBoxRead],pb_lInBox^,wLng);
          pHiBuff[nIndex].w_mBoxRead  := pHiBuff[nIndex].w_mBoxRead + wLng;
          pHiBuff[nIndex].w_mBoxSize  := pHiBuff[nIndex].w_mBoxSize + wLng;
          pHiBuff[nIndex].w_mBoxMesCt := pHiBuff[nIndex].w_mBoxMesCt - 1;
          if(pHiBuff[nIndex].w_mBoxRead > pHiBuff[nIndex].w_mBoxCSize) then pHiBuff[nIndex].w_mBoxRead := 0;
          if pHiBuff[nIndex].w_mBoxMesCt=0 then ResetEvent(AE[0]) // ResetEvent(pHiBuff[nIndex].w_mEvent)
          else SetEvent(pHiBuff[nIndex].w_mEvent);
          result := wLng;
        end;
      WAIT_OBJECT_0 + 1:
        begin
          ResetEvent(AE[1]);
          Exit;
        end;
    end;
  except
    SClass.ToStringBox(ET_CRITICAL, 'Ошибка в utlbox.FGETMULT ');
  end;
End;


Описание массива в Type
Код: pascal
1.
ArrayEvents = array[0..1] of THandle;


и в классе
Код: pascal
1.
2.
     FEvents        : ArrayEvents;
     TerminateEvent : THandle;


Ну и собственно, сам вызов в Execute
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
procedure CL4Module.Execute;
Begin
   FDEFINE(BOX_L4,BOX_L4_SZ,True);
   while not Terminated do Begin
     FEvents[0] := pHiBuff[BOX_L4].w_mEvent;
     FEvents[1] := TerminateEvent;
     FGETMULT(BOX_L4, @m_nMsg, FEvents);
     if Terminated then Exit;
      if m_nL4Synchronize = 1  then Synchronize(OnHandler)
. . . 


и при закрытии программы
Код: pascal
1.
2.
3.
  pL4Module.Terminate;
  if pL4Module <> nil then FreeAndNil(pL4Module);
  . . . 


В результате:
1. Намного дольше стала запускаться программа (раза в 2-3)
2. При закрытии программы долго скачет по WaitFor, в конце-концов выдает:

28.08.2021 14:19:59 : EThread: Thread Error: Неверный дескриптор (6)
(0002CD80){knsmodule.exe} [0042DD80] utlbox.TThread.CheckThreadError (Line 9453, "utlbox" + 2) + $37
(0002CDC4){knsmodule.exe} [0042DDC4] utlbox.TThread.CheckThreadError (Line 9459, "utlbox" + 2) + $A
(0002D0C5){knsmodule.exe} [0042E0C5] utlbox.TThread.WaitFor (Line 9722, "utlbox" + 17) + $16
(0002CCBB){knsmodule.exe} [0042DCBB] utlbox.TThread.Destroy (Line 9428, "utlbox" + 6) + $3
(0096945D){knsmodule.exe} [00D6A45D] utlbox.CThread.Destroy (Line 77, "utlThread.pas" + 14) + $9
(0090D872){knsmodule.exe} [00D0E872] utlbox.CL4Module.Destroy (Line 83, "knsl4module.pas" + 13) + $9
(0000341C){knsmodule.exe} [0040441C] utlbox.m_nSpeedList + $0
. . .
Где я мог опять накосячить%(
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093637
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
О, безупречный WaitFor :-) взял попкорн :-)
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093640
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BorodaOleg
Код: pascal
1.
WaitForMultipleObjects(2, @AE, False, 1)

1. Должно быть
Код: pascal
1.
WaitForMultipleObjects(2, @AE, False, INFINITE)

Еще лучше
Код: pascal
1.
WaitForMultipleObjects(2, @AE[0], False, INFINITE)

но это уже не принципиально. Скорее защита от будущих потенциальных ошибок

2. Этот кусок
BorodaOleg
Код: pascal
1.
2.
3.
4.
5.
WAIT_OBJECT_0 + 1:
        begin
          ResetEvent(AE[1]);
          Exit;
        end;

выбросить вообще
3.
BorodaOleg
и при закрытии программы
Код: pascal
1.
2.
3.
  pL4Module.Terminate;
  if pL4Module <> nil then FreeAndNil(pL4Module);
  . . . 

Я же написал
_Vasilisk_
3. Весь код уничтожения потока сократить до одной строчки
Код: pascal
1.
FreeAndNil(pL4Module);


4.
BorodaOleg
2. При закрытии программы долго скачет по WaitFor, в конце-концов выдает:
28.08.2021 14:19:59 : EThread: Thread Error: Неверный дескриптор (6)
А зачем вы поставили FreeOnTerminate := True?
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093644
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
BorodaOleg
и при закрытии программы
Код: pascal
1.
2.
3.
  pL4Module.Terminate;
  if pL4Module <> nil then FreeAndNil(pL4Module);
  . . . 


Я же написал
_Vasilisk_
3. Весь код уничтожения потока сократить до одной строчки
Код: pascal
1.
FreeAndNil(pL4Module);


BorodaOleg
Где я мог опять накосячить%(

Много где. Раз ты такое пишешь, даже после советов ничего не делая - значит, ты не хочешь разбираться в том, что делаешь.
А стоило бы, хотябы в азах.
Зайди, для начала, в функции FreeAndNil, методы TObject.Free и TThread.Destroy и проштудируй их.
В идеале ты в этом случае сможешь понять, почему не нужны лишние Terminate и проверки на Assigned.

И еще 2 момента:
1. Ты создал именованный эвэнт. Это не нужно, поставь вместо имени nil (опять же, из-за нечтения документации и кода). Это не очень принципиально, но всё же.
2. Если ты в конструкторе класса что-то создаёшь - значит, надо убивать это в деструкторе, логика такая. Ты TerminateEvent создал, а убить забыл. Это лучше сделать после inherited Destroy (ведь пока он не выполнится - еще возможно его использование), и это касается всего.
Т.е. примерно такой:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
destructor CThread.Destroy;
begin
  Terminate; // Важно - Для того, чтобы сразу после сработки TerminateEvent переменная Terminated уже была выставлена
  SetEvent(TerminateEvent);
  FreeAndNil(SenderClass); // Это тоже надо переносить после inherited Destroy!!!
  inherited Destroy;
  CloseHandle( TerminateEvent );
end;
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093647
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Код: pascal
1.
 Terminate; // Важно - Для того, чтобы сразу после сработки TerminateEvent переменная Terminated уже была выставлена

Согласен. Хотя событие без автосброса, но так лучше
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093673
BorodaOleg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем кто подсказал/научил, все заработало! :)
Осталось еще 18 потоков привести к общему знаменателю, и все Ок! :)
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093674
BorodaOleg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_

. . .
4.
BorodaOleg
2. При закрытии программы долго скачет по WaitFor, в конце-концов выдает:
28.08.2021 14:19:59 : EThread: Thread Error: Неверный дескриптор (6)
А зачем вы поставили FreeOnTerminate := True?

Читал раньше:

//Можно указать что после завершения кода поток завершится автоматически:
MyThread.FreeOnTerminate:=true;

А так как я потоки использовал без WaitFor, меня это устраивало.
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093675
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BorodaOlegЧитал раньше://Можно указать что после завершения кода поток
завершится автоматически:MyThread.FreeOnTerminate:=true
Никогда больше не посещайте ресурс где Вы прочли эту глупость.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093678
BorodaOleg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
YuRock

Много где. Раз ты такое пишешь, даже после советов ничего не делая - значит, ты не хочешь разбираться в том, что делаешь.
А стоило бы, хотябы в азах.
Зайди, для начала, в функции FreeAndNil, методы TObject.Free и TThread.Destroy и проштудируй их.
В идеале ты в этом случае сможешь понять, почему не нужны лишние Terminate и проверки на Assigned.


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;


Это, на случай, из исходников Delphi 7, файл SysUtils.pas. Я в курсе, что даже с nil FreeAndNil не ляснется, но вот я в этом проекте неоднократно встречался когда объект создается в классе A, передается в класс B, а оттуда в класс С, где его добросовестно убивают (не нужен стал, видать), а потом пытаются убить еще и в классе A. А чтобы "глупая ошибка" Access violation не выскакивала, они его в пустой try..except упаковывают. Как это можно отследить, я так и не смог допетрить. Лазил по всему тексту, отслеживал пустые исключения.

YuRock

И еще 2 момента:
. . .
2. Если ты в конструкторе класса что-то создаёшь - значит, надо убивать это в деструкторе, логика такая. Ты TerminateEvent создал, а убить забыл. Это лучше сделать после inherited Destroy (ведь пока он не выполнится - еще возможно его использование), и это касается всего.

Тут каюсь, забыл. Заколупался просто, 7-й день без выходных - мозги варить отказываются %(
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093679
BorodaOleg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

BorodaOlegЧитал раньше://Можно указать что после завершения кода поток
завершится автоматически:MyThread.FreeOnTerminate:=true

Никогда больше не посещайте ресурс где Вы прочли эту глупость.


https://thedelphi.ru/les/les54.php
Не буду :)
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093698
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BorodaOleg
Я в курсе, что даже с nil FreeAndNil не ляснется
Тут дело не в FreeAndNil, а в Free, которое вызывается в FreeAndNil. А в Free уже проверка на Assigned есть.

BorodaOleg
но вот я в этом проекте неоднократно встречался когда объект создается в классе A, передается в класс B, а оттуда в класс С, где его добросовестно убивают (не нужен стал, видать), а потом пытаются убить еще и в классе A. А чтобы "глупая ошибка" Access violation не выскакивала, они его в пустой try..except упаковывают.

1. Вы этом случае не поможет лишняя проверка на Assigned (разве что глобальная переменная).
2. Засовывать в try/except освобождение по мусорному адресу - это ужас, который рано или поздно аукнется, и ты получишь порчу памяти и полный крах. Надо исправлять логику проекта. Убирание говнокода помогает такому исправлению.
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093727
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BorodaOleg


Жесть!

Рекомендую этот материал для изучения многопоточного программирования.
К сожалению, в нем не поднимается тема ожидания сразу нескольких событий. Но считаю, что там достаточно материала, чтобы можно было самостоятельно разобраться с WaitForMultipleObjects и MsgWaitForMultipleObjects.

хотя автору это уже не нужно...
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093779
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DmSer
Жесть

Виноват тот, кто придумал TThread. От него у новичков все беды.
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093798
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ъъъъъ
DmSer
Жесть

Виноват тот, кто придумал TThread. От него у новичков все беды.


Да вот как-то async/await не сразу изобрели. В последние 10 лет появляются то в одном, то в другом языке. А ведь именно это является панацеей от необходимости связываться с многопоточным программированием.
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093800
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Зачем было что-то изобретать если есть простой и понятный beginthread(ex)?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093804
ъъъъъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov
Зачем было что-то изобретать если есть простой и понятный beginthread(ex)?

Покойный Архангельский про TThread писал.
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093819
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

Зачем было что-то изобретать если есть простой и понятный beginthread(ex)?


Доп. потоки в действительности нужны только для каких-то вычислений и обработки информации. Основные причины, когда мы их используем - это обмен по сети, обмен с устройством, запросы к базе данных, работа с файлами. Благодаря async / await обмен по сети, обмен с устройством, запросы к БД, работа с файлами перебираются в главный поток и не парят программисту мозги многопоточностью.
Колоссальный выигрыш получают сервера (например TCP или HTTP-сервер), т.к. с многопоточностью не связываешься, а код получается быстрый, простой и понятный.
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093820
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer
Да вот как-то async/await не сразу изобрели. В последние 10 лет появляются то в одном, то в другом языке. А ведь именно это является панацеей от необходимости связываться с многопоточным программированием.
они как бы далеко не панацея, у них свои проблемы
но в целом что дельфи с TThread, что шарп c Async собрали все грабли с контекстом
...
Рейтинг: 0 / 0
Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
    #40093822
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
DmSer
Да вот как-то async/await не сразу изобрели. В последние 10 лет появляются то в одном, то в другом языке. А ведь именно это является панацеей от необходимости связываться с многопоточным программированием.
они как бы далеко не панацея, у них свои проблемы
но в целом что дельфи с TThread, что шарп c Async собрали все грабли с контекстом


об чём речь?
...
Рейтинг: 0 / 0
25 сообщений из 48, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Почему поток не хочет уничтожаться, постоянно крутиться в процедуре TThread.WaitFor
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]