Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1156552426
batya17
2006-08-26 04:33
2006.09.17
Звук


15-1156717348
kaif
2006-08-28 02:22
2006.09.17
Принтер Zebra - с чего начать чайнику?


2-1156750865
Steep
2006-08-28 11:41
2006.09.17
Копирование файлов


15-1156447113
Кручен-Верчен
2006-08-24 23:18
2006.09.17
Придумка.


3-1152797535
samalex
2006-07-13 17:32
2006.09.17
не работает функция upper





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский