INDY 10 TCP Server - Combine with non thread safe

2020-03-24 04:38发布

问题:

VCL is not thread safe. Therefore I guess it is not a good idea to write information to the gui in the INDY 10 TCP server.execute(...) function .

How to send information from the server execute to the VCL ?

I need to modify a TBitmap inside a tcpserver.execute function. How to make that thread safe ?

回答1:

Write stuff to the VCL thread from Indy the same way to write stuff to the VCL thread from anywhere else. Common options include TThread.Synchronize and TThread.Queue.

Modifying a standalone TBitmap should not require synchronization with the main thread. You can modify it from any thread you want, as long as you do it from only one thread at a time. You can use the standard synchronization objects like critical sections and events to make sure only one thread uses it at a time.



回答2:

the best way to synch is by creating and using a TidNotify descendant.

define a tidnotify descendant and vcl proc like this with the appropriate private fields.

TVclProc= procedure(aBMP: TBitmap) of object;

TBmpNotify = class(TIdNotify)
protected
  FBMP: TBitmap;
  FProc: TVclProc;
  procedure DoNotify; override;
public
  constructor Create(aBMP: TBitmap; aProc: TVclProc); reintroduce;
  class procedure NewBMP(aBMP: TBitmap; aProc: TVclProc);
end;

then implement it like this

{ TBmpNotify }

constructor TBmpNotify.Create(aBMP: TBitmap; aProc: TVclProc);
begin
  inherited Create;
  FBMP:= aBMP;
  FProc:= aProc;
end;

procedure TBmpNotify.DoNotify;
begin
  inherited;
  FProc(FBMP);
end;

class procedure TBmpNotify.NewBMP(aBMP: TBitmap; aProc: TVclProc);
begin
  with Create(aBMP, aProc) do
  begin
    Notify;
  end;

end;

then from the

server.execute(...)

call it like this

procedure TTCPServer.DoExecute(aContext: TIdContext);
var
  NewBMP: TBitmap;
begin
  TBmpNotify.NewBMP(NewBMP, FVclBmpProc);  
end;

Where the FVclBmpProcis a private field pointing to a procedure on the form that matches the parameter signature of TVclProc. This field should be set via a property on the server object just after creation and before starting the server.

the method on the form will be free to use the bitmap it receives without fear of thread contention, deadlock and other nasties created by accessing the VCL controls without synchronisation.



回答3:

One simple PostMessage (inside the thread) and handling message (outside the thread) was necessary to make UI updates...