Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
 TThread в Dll зависание при завершении потока  [new]
Bezlikiy
Member

Откуда:
Сообщений: 1
Есть приложение и dll на Lazarus. В длл содается и запускается поток. Он работает в длл нормально, но при попытке дождаться его завершения методом WaitFor длл и приложение, его загрузившее, зависает намертво. Как корректно дождаться завершения запущенного в длл потока?
Dll
library ThreadDll;

{$mode objfpc}{$H+}

uses
  Classes, SysUtils, Windows,
  uStartStop;

{$R *.res}

var
  SaveExit: Pointer;

// Процедура завершения работы Dll
procedure LibExit();
begin
  TestStop; // процедура остановки потока
  ExitProc := SaveExit;
end;

function Dll_Test: DWord;
begin
  result := GetTickCount;
end;

exports
  Dll_Test;

begin
  SaveExit := ExitProc;
  ExitProc := @LibExit;
  TestStart; // процедура запуска потока
end.
создаю и завершаю поток так:
unit uStartStop;

interface

uses
  Windows, Classes, SysUtils, uTestThread;

procedure TestStart;
procedure TestStop;

implementation

var
  TestThread: TTestThread;

procedure TestStart;
begin
  TestThread := TTestThread.Create(true);
  TestThread.Priority := tpNormal;
  TestThread.FreeOnTerminate := false;
  TestThread.Start;
end;

procedure TestStop;
begin
  TestThread.Terminate;
  TestThread.WaitFor; // зависает намертво
  FreeAndNil(TestThread);
end;

end.
сам код потока:
unit uTestThread;

interface

uses
  Classes, SysUtils;

type

  { TTestThread }

  TTestThread = class(TThread)
  strict private
    procedure Log(const Mess: String);
  protected
    procedure Execute; override;
  public
    constructor Create(const Value: Boolean);
    destructor Destroy; override;
  end;

implementation

procedure AddToLogTxtFile(const Text, FileName: String);
var
  TxtFile: TextFile;
begin
  if not FileExists(FileName) then
    FileClose(FileCreate(FileName));

  AssignFile(TxtFile, FileName);
  try
    {$I-}
    Append(TxtFile);
    WriteLn(TxtFile, Text);
  finally
    CloseFile(TxtFile);
    {$I+}
    IOResult;
  end;
end;

{ TTestThread }

procedure TTestThread.Log(const Mess: String);
begin
  AddToLogTxtFile(Format('%s : %s',
    [TimeToStr(Time), Mess]), '!TestThreadLog.txt');
end;

procedure TTestThread.Execute;
begin
  Log('Execute: Start'); 
  while not Terminated do
  begin
    Log('Execute: Life');
    sleep(1000);
  end;
  Log('Execute: Stop'); // запись появляется
end;

constructor TTestThread.Create(const Value: Boolean);
begin
  inherited Create(Value);
  Log('Create');
end;

destructor TTestThread.Destroy;
begin
  Log('Destroy'); // запись не появляется, т.к. зависание на WaitFor
  inherited;
end;

end.

в логе появляются следующие записи:
11:26:01 : Create
11:26:01 : Execute: Start
11:26:01 : Execute: Life
...........................
11:26:11 : Execute: Life
11:26:12 : Execute: Stop

Почему зависает на методе WaitFor?
15 фев 13, 11:56    [13930847]     Ответить | Цитировать Сообщить модератору
 Re: TThread в Dll зависание при завершении потока  [new]
GunSmoker
Member

Откуда:
Сообщений: 3110
Не в курсе как в Lazarus, а в Delphi завершение потока означает вызов события OnTerminate. Событие вызывается через Synchronize. Обработчика Synchronize в DLL по умолчанию нет - ты его сам должен написать.

Возможно, что в Lazarus что-то похожее имеет место быть.
15 фев 13, 14:57    [13932261]     Ответить | Цитировать Сообщить модератору
 Re: TThread в Dll зависание при завершении потока  [new]
Arioch
Member

Откуда:
Сообщений: 10967
GunSmoker,

Емнип дело в том, что WaitFor работает через очередь сообщений.

Т.е. там нужно в инициализации DLL написать что-то вроде такого

DLL.Application.Handle := EXE.Application.Handle


а при окончании соотв. его занулять
15 фев 13, 16:07    [13932785]     Ответить | Цитировать Сообщить модератору
 Re: TThread в Dll зависание при завершении потока  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11163
Bezlikiy
Почему зависает на методе WaitFor?
Читать
16 фев 13, 00:44    [13935235]     Ответить | Цитировать Сообщить модератору
 Re: TThread в Dll зависание при завершении потока  [new]
GunSmoker
Member

Откуда:
Сообщений: 3110
...а слона-то я и не заметил.

Тогда ссылку в тему.

Нужно изменить дизайн DLL, введя в неё экспортируемую функцию Done, которую вызывающий должен будет вызвать непосредственно перед выгрузкой DLL.
16 фев 13, 11:07    [13935665]     Ответить | Цитировать Сообщить модератору
 Re: TThread в Dll зависание при завершении потока  [new]
Warstone
Member

Откуда:
Сообщений: 4896
Блог
А выкинуть VCL и написать на API с WaitForObject?
17 фев 13, 01:32    [13937794]     Ответить | Цитировать Сообщить модератору
 Re: TThread в Dll зависание при завершении потока  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 11163
Warstone
А выкинуть VCL и написать на API с WaitForObject?
Пофиг. Вы читали ссылки? Нельзя Wait-функции вызывать в DllMain
17 фев 13, 18:44    [13939170]     Ответить | Цитировать Сообщить модератору
Все форумы / Delphi Ответить