Форум: "Начинающим";
Текущий архив: 2006.09.17;
Скачать: [xml.tar.bz2];
ВнизНе высвобождается поток Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.041 c