[英]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.Synchronize
和TThread.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.