Вы можете создать потокобезопасный класс Queue, который используется в модели Producer-Consumer . Ваш класс-потомок TThread должен иметь экземпляр этого класса Queue.
Когда вы запускаете свое приложение, ваша очередь пуста, и ваш поток регистрации блокируется в ожидании очереди. Когда вы помещаете новую строку в очередь из основного потока, ваша очередь запускает поток регистрации, ваш поток регистрации просыпается и выталкивает элементы из очереди до тех пор, пока очередь снова не станет пустой.
Чтобы реализовать очередь в Delphi 2010 , вы можете использовать TQueue универсальный класс в качестве базового типа и использовать System.TMonitor для синхронизации. В Delphi XE уже существует класс, который реализует это для вас, с именем TThreadedQueue . Поэтому, если вы используете Delphi XE, создайте экземпляр TThreadedQueue и в своем потоке ведения журнала попытайтесь вызвать его метод PopItem ().
EDIT:
Вот пример потока логирования, который получает строковые журналы:
unit uLoggingThread;
interface
uses
SysUtils, Classes, Generics.Collections, SyncObjs {$IFDEF MSWINDOWS} , Windows {$ENDIF};
type
TLoggingThread = class(TThread)
private
FFileName : string;
FLogQueue : TThreadedQueue<string>;
protected
procedure Execute; override;
public
constructor Create(const FileName: string);
destructor Destroy; override;
property LogQueue: TThreadedQueue<string> read FLogQueue;
end;
implementation
{ TLoggingThread }
constructor TLoggingThread.Create(const FileName: string);
begin
inherited Create(False);
FFileName := FileName;
FLogQueue := TThreadedQueue<string>.Create;
end;
destructor TLoggingThread.Destroy;
begin
FLogQueue.Free;
inherited;
end;
procedure TLoggingThread.Execute;
var
LogFile : TFileStream;
FileMode : Word;
ALog : string;
begin
NameThreadForDebugging('Logging Thread');
// FreeOnTerminate := True;
if FileExists(FFileName) then
FileMode := fmOpenWrite or fmShareDenyWrite
else
FileMode := fmCreate or fmShareDenyWrite;
LogFile := TFileStream.Create(FFileName,FileMode);
try
while not Terminated do
begin
ALog := FLogQueue.PopItem;
if (ALog <> '') then
LogFile.Write(ALog[1],Length(ALog)*SizeOf(Char));
end;
finally
LogFile.Free;
end;
end;
end.
Этот потомок TThread использует объект TThreadedQueue в качестве буфера. Когда вызывается FLogQueue.PopItem, если очередь пуста, поток переходит в спящий режим и ожидает, пока что-то не будет помещено в очередь. Когда элемент доступен в очереди, поток извлекает его и записывает в файл. Это очень простой код, позволяющий вам понять основы того, что вы должны делать.
А вот пример кода для формы, которая выполняется в контексте основного потока и регистрирует пример сообщения:
unit fMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, uLogginThread;
type
TfrmMain = class(TForm)
btnAddLog: TButton;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure btnAddLogClick(Sender: TObject);
private
FLoggingThread : TLoggingThread;
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.FormCreate(Sender: TObject);
begin
FLoggingThread := TLoggingThread.Create(ExtractFilePath(Application.ExeName) + 'Logs.txt');
end;
procedure TfrmMain.FormDestroy(Sender: TObject);
begin
FLoggingThread.Terminate;
FLoggingThread.LogQueue.DoShutDown;
FLoggingThread.WaitFor;
FreeAndNil(FLoggingThread);
end;
procedure TfrmMain.btnAddLogClick(Sender: TObject);
begin
FLoggingThread.LogQueue.PushItem('This is a test log. ');
end;
end.
Здесь экземпляр TLoggingThread создается при инициализации формы. Когда вы нажимаете btnAddLog, образец сообщения отправляется в поток регистратора через его свойство LogQueue.
Обратите внимание на завершение потока в методе FormDestroy. Сначала потоку сообщается о том, что он завершен, а затем мы сообщаем LogQueue об освобождении любой блокировки, поэтому, если поток средства ведения журнала ожидает очереди, он автоматически проснется после вызова DoShutDown. Затем мы ожидаем завершения потока, вызывая метод WaitFor, и в конечном итоге уничтожаем экземпляр потока.
Удачи