Создайте свой класс потока. Я так поступаю для полного контроля над потоком.
Например как-то так :
TBeePosMessageThread = class(TThread)
private
function ExtractData(aPacket : PBeePosDataPacket): string;
procedure ProcessPacket(aPacket : pointer);
procedure DoProcess(aPacket : PBeePosDataPacket);
protected
procedure Execute; override;
end;
implementation
{ TBeePosMessageThread }
procedure TBeePosMessageThread.DoProcess(aPacket: PBeePosDataPacket);
var
jObj : TJSONObject;
sObj : string;
cmd : string;
typ : string;
oObj : string;
lock : boolean;
id, uid : TBeePosID;
price : Currency;
qty : double;
table : integer;
begin
sObj := ExtractData(aPacket);
jObj := nil;
try
jObj := TJSONObject.ParseJSONValue(sObj) as TJSONObject;
cmd := jObj.Values['command'].Value;
typ := jObj.Values['type'].Value;
if cmd = 'update' then
begin
//New order received
if typ = 'order' then
begin
oObj := (jObj.Values['object'] as TJSONObject).ToJSON;
Synchronize(procedure
begin
MainFrm.OrderReceived(oObj);
end);
end;
//order lock changed
if typ = 'orderlock' then
begin
try
lock := jObj.Values['value'].Value.ToBoolean;
except
end;
try
id := jObj.Values['object'].Value.ToInt64;
except
end;
try
uid := jObj.Values['user'].Value.ToInt64;
except
end;
try
table := jObj.Values['table'].Value.ToInteger;
except
end;
Synchronize(procedure
begin
MainFrm.SetOrderLocked(id, uid, lock, table);
end);
end;
//menu item stock changed
if typ = 'menuitem' then
begin
id := 0;
try
id := jObj.Values['object'].Value.ToInt64;
except
end;
try
price := jObj.Values['price'].Value.ToDouble;
except
end;
try
qty := jObj.Values['qty'].Value.ToDouble;
except
end;
Synchronize(procedure
begin
MainFrm.MenuStockChanged(id, qty, price);
end);
end;
//ingredient stock changed
if typ = 'ingredient' then
begin
id := 0;
try
id := jObj.Values['object'].Value.ToInt64;
except
end;
try
price := jObj.Values['price'].Value.ToDouble;
except
end;
try
qty := jObj.Values['qty'].Value.ToDouble;
except
end;
Synchronize(procedure
begin
MainFrm.IngredientStockChanged(id, qty, price);
end);
end;
//Customer received
if typ = 'customer' then
begin
oObj := (jObj.Values['object'] as TJSONObject).ToJSON;
Synchronize(procedure
begin
MainFrm.CustomerAdded(oObj);
end);
end;
end;
if cmd = 'delete' then
begin
if typ = 'order' then
begin
try
id := jObj.Values['object'].Value.ToInt64;
except
end;
Synchronize(procedure
begin
MainFrm.RemoveOrder(id);
end);
end;
end;
finally
if Assigned(jObj) then
FreeAndNil(jObj);
end;
end;
procedure TBeePosMessageThread.Execute;
var
Len : integer;
Buf : TIdBytes;
pBuf : pointer;
begin
while not Terminated do
begin
sleep(10);
if MainFrm.MessagingClient.Connected then
begin
len := 0;
try
if MainFrm.MessagingClient.IOHandler.CheckForDataOnSource(100) then
begin
len := MainFrm.MessagingClient.IOHandler.InputBuffer.Size;
try
MainFrm.MessagingClient.IOHandler.ReadBytes(Buf, len, false);
GetMem(pBuf, len);
Move(Buf[0], pBuf^, len);
ProcessPacket(pBuf);
finally
SetLength(Buf, 0);
end;
end;
except
on E:EIdException do
Synchronize(procedure
begin
MainFrm.MessagingClientDisconnected(nil);
end);
end;
end
else
begin
TTask.Run(procedure
begin
Synchronize(procedure
begin
MainFrm.MessagingClientDisconnected(nil);
end)
end);
Exit;
end;
end;
end;
function TBeePosMessageThread.ExtractData(aPacket: PBeePosDataPacket): string;
var
str : string;
begin
DecryptPacket(aPacket.Data, aPacket.BufferSize);
SetLength(str, (aPacket.BufferSize div SizeOf(Char)) - 1);
Move(aPacket.Data^, str[1], aPacket.BufferSize);
Result := TIdDecoderMIME.DecodeString(str);
end;
procedure TBeePosMessageThread.ProcessPacket(aPacket: pointer);
var
aDataPacket : PBeePosDataPacket;
begin
try
if TBeePosContext.CheckPacket(aPacket) then
begin
GetMem(aDataPacket, SizeOf(TBeePosDataPacket));
aDataPacket.Header := PBeePosDataPacket(aPacket).Header;
aDataPacket.BufferSize := PBeePosDataPacket(aPacket).BufferSize;
aDataPacket.Data := nil;
GetMem(aDataPacket.Data, aDataPacket.BufferSize);
Move(pointer(NativeUInt(aPacket) + SizeOf(TBeePosMessagePacket))^,
aDataPacket.Data^, aDataPacket.BufferSize);
try
DoProcess(aDataPacket);
finally
FreeMem(aDataPacket.Data);
end;
end
finally
FreeMem(aDataPacket);
FreeMem(aPacket);
end;
end;