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