5

我正在使用 TIDTCPServer 组件。据我了解,事件ServerTCPExecute(AContext: TIdContext) 不同步。同步它的最佳方法是什么?我需要将数据发送到主线程并让它们返回格式化答案。

我正在使用 Indy 10.5.8.0。

方法一

像这样我应该处理关键部分以将数据从非同步函数传递到应用程序吗?

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

2 回答 2

12

正确的方法是使用 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(). 如果在服务器尝试与主线程同步时主线程尝试停用服务器,您将死锁主线程和服务器。

于 2012-08-29T19:15:00.393 回答
0

在我的应用程序中,我正在使用以下代码:

procedure MainThreadProcedure;
begin
  ...
end;
.
.
.
procedure IdTCPServerExecute(AContext: TIDContext);
begin
  TIdYarnOfThread(AContext.Yarn).Thread.Synchronize(MainThreadProcedure);
end;

如果需要访问主线程变量,请务必使用临界区或其他同步对象ServerTCPExecute

于 2012-08-29T10:08:50.793 回答