INDY 10 TCP Server - Combine with non thread safe VCL Code

后端 未结 3 1709
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-14 03:22

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 t

相关标签:
3条回答
  • 2021-01-14 03:39

    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.

    0 讨论(0)
  • 2021-01-14 03:40

    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.

    0 讨论(0)
  • 2021-01-14 03:41

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

    0 讨论(0)
提交回复
热议问题