繁体   English   中英

INDY 10 TCP Server-与非线程安全的VCL代码结合使用

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

VCL不是线程安全的。 因此,我认为在INDY 10 TCP server.execute(...)函数中将信息写入gui不是一个好主意。

如何从服务器执行信息发送到VCL?

我需要在tcpserver.execute函数中修改TBitmap。 如何使该线程安全?

从Indy向VCL线程写入内容的方法与从其他任何地方向VCL线程写入内容的方法相同。 常用选项包括TThread.SynchronizeTThread.Queue

修改独立的TBitmap不需要与主线程同步。 您可以从任何所需的线程中对其进行修改,只要一次仅从一个线程中进行修改即可。 您可以使用诸如关键节和事件之类的标准同步对象来确保一次仅一个线程使用它。

同步的最佳方法是创建并使用TidNotify后代。

用适当的私有字段定义一个tidnotify后代和vcl proc。

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;

然后像这样实现

{ 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;

然后从

server.execute(...)

这样称呼它

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

FVclBmpProcis是一个私有字段,指向与TVclProc的参数签名匹配的表单上的过程。 在创建之后和启动服务器之前,应通过服务器对象上的属性设置此字段。

窗体上的方法将可以自由使用接收到的位图,而不必担心线程争用,死锁和其他由于不同步而访问VCL控件而造成的麻烦。

一个简单的PostMessage(在线程内)和处理消息(在线程外)对于进行UI更新是必需的...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM