Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.09.17;
Скачать: CL | DM;

Вниз

Не высвобождается поток   Найти похожие ветки 

 
kami ©   (2006-08-24 10:46) [0]

Прохожу MemProof - ом свою программу. Периодически (не могу выявить закономерность) MemProof показывает, что поток, создаваемый в моем классе не высвобождается. Подскажите, что не так? Или опять нельзя верить MemProofу ?

код :

constructor TmyClass.Create;
begin
 FhWindow:=AllocateHWND(WndProc);
 // инициализации, не имеющие отношения к потоку
 FmyThread:=TmyThread.Create(FhWindow);
 // тоже ничего общего с потоком
end;

destructor TmyClass.Destroy; // вызывается однозначно
begin
 PostThreadMessage(FmyThread.ThreadID, msgThreadClose, 0, 0);
 DeallocateHWND(FhWindow);
end;

//============== сам поток======================
constructor TmyThread.Create(hWindow:THandle);
begin
 inherited Create(True);
 FhWindow := hWindow;
 FreeOnTerminate := True;
 Resume;
end;

procedure TmyThread.Execute;
var
 msg: TMsg;
begin
 PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
 while not Terminated do
   begin
     GetMessage(msg, 0, 0, 0);
     if msg.hwnd = 0 then
       case msg.Message of
         msgNeedCalc:
           DoCalc; // здесь отсылается несколько сообщений (PostMessage в FhWindow), сама
                   // процедура выполняется недолго, никаких Synchronize нет.
         msgThreadClose:
           Terminate;
       end;
     DispatchMessage(msg);
   end;
end;


Чуть не забыл (у MagicForum при добавлении вопроса нет чекбоксов версии Windows и Delphi) :
WinXP SP1, Delphi 7 (без апдейтов), MemProof 0.9.5.0


 
Сергей М. ©   (2006-08-24 11:17) [1]

procedure TmyThread.Execute;
var
msg: TMsg;
begin
PeekMessage(msg, 0, WM_USER, WM_USER, PM_NOREMOVE);
try
while not Terminated do
  begin
    GetMessage(msg, 0, 0, 0);
//     if msg.hwnd = 0 then //это лишнее
      case msg.Message of
        msgNeedCalc: DoCalc;
        msgThreadClose: Terminate; // <-- здесь брейкпойнт ловишь ?
      end;
//     DispatchMessage(msg); //это тоже лишнее
  end;
 except
// .. если  возникли непредвиденные исключения, здесь их можно запротоколировать хотя бы в целях отладки ..
 end;
end;


 
kami ©   (2006-08-24 11:26) [2]

Сергей М. ©   (24.08.06 11:17) [1]
здесь брейкпойнт ловишь

При проходе отладчиком все ловится, деструктор потока вызывается, да и исключений-то не может быть, нечему там исключаться...
MemProof, если срабатывает исключение и приложение завершается аварийно, вообще ничего не говорит о освобожденных ресурсах...


> это лишнее

Скопировано почти "1х1" с TServiceThread :) (поток - в обычном приложении, к сервису отношения не имеет).

Попробую с try/except.


 
Сергей М. ©   (2006-08-24 11:41) [3]

Пробуй так:

TmyThread = class(TThread)
..
 procedure MsgDoCalc(var Message: TMessage); message msgNeedCalc;
..
end;

..
constructor TmyClass.Create;
begin
FhWindow:=AllocateHWND(WndProc);
..
FmyThread:=TmyThread.Create(FhWindow);
..
end;

destructor TmyClass.Destroy;
begin
PostThreadMessage(FmyThread.ThreadID, WM_QUIT, 0, 0);
DeallocateHWND(FhWindow);
end;

constructor TmyThread.Create(hWindow:THandle);
begin
inherited Create(True);
FhWindow := hWindow;
FreeOnTerminate := True;
Resume;
while not PostThreadMessage(ThreadId, WM_USER, 0, 0) do sleep(0);
end;

procedure TmyThread.MsgDoCalc(var Message: TMessage);
begin
 DoCalc;
end;

procedure TmyThread.Execute;
var
 msg: TMsg;
begin
 try
   while not Terminated and GetMessage(msg, 0, 0, 0) do
     Dispatch(Msg.Message);
  except
 ..
  end;
end;



> Скопировано почти "1х1" с TServiceThread


Копировать что-либо надо с умом, обдуманно)


 
kami ©   (2006-08-24 13:45) [4]

Сергей М. ©   (24.08.06 11:41) [3]
> Копировать что-либо надо с умом, обдуманно)

Действительно, что это я, надо ремарки в MSDN читать внимательнее. Спасибо, про ненужность DispatchMessage и ожидание создания очереди сообщений не знал раньше :) А на кой тогда это использовали в TServiceThread ?

Вроде, проблема решена. По крайней мере, из 25 запусков ни одного невысвобожденного потока. Правда, не стал выносить обработку msgNeedCalc в отдельную процедуру.


 
зайдивчат   (2006-08-24 13:50) [5]


> А на кой тогда это использовали в TServiceThread ?


А откуда TServiceThread знает, будешь ты создавать окна в своем наследнике TService или не будешь ?


> не стал выносить обработку msgNeedCalc в отдельную процедуру


А зря.
Простое, изящное, наглядное и надежное решение)


 
Сергей М. ©   (2006-08-24 13:52) [6]


> kami ©   (24.08.06 13:45) [4]


DispatchMessage() будет вызван вхолостую, потому что нет окон.


 
kami ©   (2006-08-24 14:05) [7]

зайдивчат   (24.08.06 13:50) [5]
и надежное решение


Чем надежнее, чем :) выборка в цикле Execute ?


 
Сергей М. ©   (2006-08-24 14:24) [8]


> kami ©   (24.08.06 14:05) [7]


> Чем надежнее, чем .. выборка


Не знаю что он там имел в виду под термином "надежность", но собственно к выборке это не имеет отношения. К диспетчеризации - да, но не к выборке.
Просто грех не воспользоваться готовым механизмом диспетчеризации, предлагаемым классом TObject.



Страницы: 1 вся ветка

Текущий архив: 2006.09.17;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.151 c
2-1156757046
Rubey
2006-08-28 13:24
2006.09.17
Форма с заставкой


2-1156243280
MASTAFA
2006-08-22 14:41
2006.09.17
Как это делается?


2-1156772503
vase21
2006-08-28 17:41
2006.09.17
график


15-1156616467
batya17
2006-08-26 22:21
2006.09.17
каую прогу посоветуете для создание инсталяшек?


15-1155287614
vajo
2006-08-11 13:13
2006.09.17
Штрафы за использование пиратского ПО