VCL不是線程安全的。因此,我想在INDY 10 TCP server.execute(...)
函數中向gui寫入信息並不是一個好主意。INDY 10 TCP服務器 - 結合非線程安全VCL代碼
如何從服務器執行信息發送到VCL?
我需要修改tcpserver.execute
函數中的TBitmap。如何使線程安全?
VCL不是線程安全的。因此,我想在INDY 10 TCP server.execute(...)
函數中向gui寫入信息並不是一個好主意。INDY 10 TCP服務器 - 結合非線程安全VCL代碼
如何從服務器執行信息發送到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;
然後從那裏FVclBmpProcis一個私有字段指向程序
server.execute(...)
這樣稱呼它
procedure TTCPServer.DoExecute(aContext: TIdContext);
var
NewBMP: TBitmap;
begin
TBmpNotify.NewBMP(NewBMP, FVclBmpProc);
end;
在表格上hat匹配TVclProc的參數簽名。該字段應該在創建之後和啓動服務器之前通過服務器對象上的屬性進行設置。
表單上的方法可以自由使用它接收到的位圖,而不用擔心通過訪問VCL控件創建的線程爭用,死鎖和其他缺陷而無需同步。
感謝Mike,我將在我的程序中測試該代碼; Delphi和INDY 10的stackoverflow上現在有許多有用的代碼sniplets;有人應該將其複製到E書:-) – user1769184
一個簡單的PostMessage的(線程內)和處理消息(線程外)是必要的,使UI更新...
我做了Id.notify梅索德調用內部的所有VCL的東西,但只適用80%成功... – user1769184
[code] procedure TServerMainForm.IdTCPServerExecute(AContext:TIdContext); var .... begin /// /// TIdNotify.NotifyMethod(ShowStartServerMessage); ...... – user1769184
'TIdNotify.NotifyMethod'異步運行,因爲它只不過是調用'TThread.Queue'。難道20%你想要做的事情需要同步訪問VCL嗎? –