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 ?
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.
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.
One simple PostMessage (inside the thread) and handling message (outside the thread) was necessary to make UI updates...