Вот простой пример накидал. Главная форма, поток, две очереди (очередь запросов и очередь ответов). Вы в главной форме вбивате два числа, и нажимаете кнопку по своему усмотрению (прибавить, умножить, разделить). Числа отправляются в Очередь запросов, поток получает задачу, выполняет и отправляет ответ в очередь ответов. Главная форма, в Application.OnIdle ждет получения результатов проверяя Очередь ответов, при получении добавляет их в Memo. Все. Проект прилагаю в архиве, вот листинг:
unit UnitFormMain;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
System.Generics.Collections, FMX.StdCtrls, FMX.Edit, FMX.EditBox,
FMX.NumberBox, FMX.Layouts, FMX.Controls.Presentation, FMX.ScrollBox, FMX.Memo;
type
TThreadOperation = (Sum, Mult, Divinity);
TThreadDataRequest = record
A : Double;
B : Double;
Operation : TThreadOperation;
end;
TThreadDataAnswer = record
Operation : TThreadOperation;
A : Double;
B : Double;
X : Double;
ErrorMessage : String;
end;
TQueueRequest = TThreadedQueue<TThreadDataRequest>;
TQueueAnswer = TThreadedQueue<TThreadDataAnswer>;
TExcampleThread = class(TThread)
protected
FQueueRequest: TQueueRequest;
FQueueAnswer: TQueueAnswer;
procedure Execute; override;
public
constructor Create(AQueueRequest : TQueueRequest; AQueueAnswer : TQueueAnswer); reintroduce;
end;
TFormMain = class(TForm)
Memo: TMemo;
Layout1: TLayout;
Label1: TLabel;
Label2: TLabel;
ButtonSum: TButton;
ButtonMult: TButton;
ButtonDiv: TButton;
EditA: TEdit;
EditB: TEdit;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure ButtonClick(Sender: TObject);
private
{ Private declarations }
FQueueRequest: TQueueRequest; // Очередь запросов
FQueueAnswer : TQueueAnswer; // Очередь ответов
FExcampleThread : TExcampleThread;
procedure OnApplicationIdle(Sender : TObject; var Done: Boolean);
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
{$R *.fmx}
procedure TFormMain.FormCreate(Sender: TObject);
begin
FQueueRequest:=TQueueRequest.Create(10, 1000, 10);
FQueueAnswer:=TQueueAnswer.Create(10, 1000, 10);
Application.OnIdle:=OnApplicationIdle;
FExcampleThread:=TExcampleThread.Create(FQueueRequest, FQueueAnswer);
end;
procedure TFormMain.FormDestroy(Sender: TObject);
begin
if Assigned(FExcampleThread) then
begin
FExcampleThread.Terminate;
FExcampleThread.WaitFor;
FExcampleThread.Free;
end;
if Assigned(FQueueRequest) then
FQueueRequest.Free;
if Assigned(FQueueAnswer) then
FQueueAnswer.Free;
end;
procedure TFormMain.OnApplicationIdle(Sender : TObject; var Done: Boolean);
Var AThreadDataAnswer : TThreadDataAnswer;
S : String;
begin
if FQueueAnswer.PopItem(AThreadDataAnswer) = TWaitResult.wrSignaled then
begin
case AThreadDataAnswer.Operation of
TThreadOperation.Sum : S:=' + ';
TThreadOperation.Mult : S:=' * ';
TThreadOperation.Divinity : S:=' / ';
end;
S:=AThreadDataAnswer.A.ToString + S + AThreadDataAnswer.B.ToString + ' = ';
if Not AThreadDataAnswer.ErrorMessage.IsEmpty then
S:=S + AThreadDataAnswer.ErrorMessage
else
S:=S + AThreadDataAnswer.X.ToString;
Memo.Lines.Add(S);
end;
end;
constructor TExcampleThread.Create(AQueueRequest : TQueueRequest; AQueueAnswer : TQueueAnswer);
begin
FQueueRequest:=AQueueRequest;
FQueueAnswer:=AQueueAnswer;
Inherited Create(False);
end;
procedure TExcampleThread.Execute;
Var AThreadDataRequest : TThreadDataRequest;
AThreadDataAnswer : TThreadDataAnswer;
begin
while Not Terminated do
begin
if FQueueRequest.PopItem(AThreadDataRequest) = TWaitResult.wrSignaled then
begin
AThreadDataAnswer.Operation:=AThreadDataRequest.Operation;
AThreadDataAnswer.ErrorMessage:='';
AThreadDataAnswer.A:=AThreadDataRequest.A;
AThreadDataAnswer.B:=AThreadDataRequest.A;
AThreadDataAnswer.X:=0;
try
case AThreadDataRequest.Operation of
TThreadOperation.Sum : AThreadDataAnswer.X:=AThreadDataRequest.A + AThreadDataRequest.B;
TThreadOperation.Mult : AThreadDataAnswer.X:=AThreadDataRequest.A * AThreadDataRequest.B;
TThreadOperation.Divinity : AThreadDataAnswer.X:=AThreadDataRequest.A / AThreadDataRequest.B;
end;
except
on E : Exception do
AThreadDataAnswer.ErrorMessage:=E.Message;
end;
FQueueAnswer.PushItem(AThreadDataAnswer);
end;
TThread.Sleep(10);
end;
end;
procedure TFormMain.ButtonClick(Sender: TObject);
Var AThreadDataRequest : TThreadDataRequest;
begin
AThreadDataRequest.A:=EditA.Text.ToDouble;
AThreadDataRequest.B:=EditB.Text.ToDouble;
Case TButton(Sender).Tag of
1 : AThreadDataRequest.Operation:=TThreadOperation.Sum;
2 : AThreadDataRequest.Operation:=TThreadOperation.Mult;
3 : AThreadDataRequest.Operation:=TThreadOperation.Divinity;
End;
FQueueRequest.PushItem(AThreadDataRequest);
end;
end.
test116 TThreadedQueue.zip