我使用的是TIDTCPServer组件。据我所知,事件ServerTCPExecute(AContext: TIdContext)
未同步。同步它的最佳方式是什么?我需要将数据发送到主线程,并将它们返回到格式应答。
我使用的是印地10.5.8.0。
方法1
我应该处理将数据从非同步函数传递到应用程序的关键部分吗?
var data:string;
.
.
.
procedure MainThreadProcedure;
begin
...
end;
.
.
.
procedure IdTCPServerExecute(AContext: TIDContext);
var tmp: string;
begin
.
.
.
EnterCriticalSection(cs);
data:= tmp;
TIdYarnOfThread(AContext.Yarn).Thread.Synchronize(MainThreadProcedure);
LeaveCriticalSection(cs);
end;
正确的方法是使用Indy的TIdSync
类,而不是直接访问Indy的内部线程,例如:
uses
..., IdSync;
type
TMySync = class(TIdSync)
protected
procedure DoSynchronize; override;
public
data: string;
end;
procedure TMySync.DoSynchronize;
begin
// this runs in the main thread
// use data as needed...
end;
procedure IdTCPServerExecute(AContext: TIDContext);
var
tmp: string;
sync: TMySync;
begin
tmp := ...;
sync := TMySync.Create;
try
sync.data := tmp;
sync.Synchronize;
finally
Sync.Free;
end;
end;
只要小心执行任何同步操作,无论是TIdSync
还是TThread.Synchronize()
。如果主线程试图停用服务器,而服务器正试图与主线程同步,则会使主线程和服务器死锁。
在我的应用程序中,我使用以下代码:
procedure MainThreadProcedure;
begin
...
end;
.
.
.
procedure IdTCPServerExecute(AContext: TIDContext);
begin
TIdYarnOfThread(AContext.Yarn).Thread.Synchronize(MainThreadProcedure);
end;
如果需要访问ServerTCPExecute
中的主线程变量,请确保使用关键部分或其他同步对象