【问题标题】:Indy synchronize ServerTCPExecuteIndy 同步 ServerTCPExecute
【发布时间】:2012-08-23 21:52:29
【问题描述】:

我正在使用 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;

【问题讨论】:

    标签: multithreading delphi indy


    【解决方案1】:

    正确的方式是使用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()。如果在服务器尝试与主线程同步时,主线程尝试停用服务器,则会导致主线程和服务器都死锁。

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 感谢您的代码。我应该像问题方法 1 中描述的那样处理关键部分吗?
      • 是的。但是,在同步之前离开关键部分,否则如果你打算在MainThreadProcedure中输入主线程,你的主线程将冻结@
      • 看起来同步在这种情况下不起作用,因为如果您查看线程调试器,您会发现 MainThreadProcedure 的线程 ID 与主应用程序线程不同。
      • 我不知道线程 ID,但这段代码在我的具有 500 多个 TCPClients 的应用程序中运行良好。您是否遇到访问冲突或内存损坏?
      • 看起来我发现了问题。 TIdYarnOfThread(AContext.Yarn).Thread.Synchronize(MainThreadProcedure); 将代码与主线程同步,但我需要使用在另一个线程(不是主线程)中起作用的对象。不知道该怎么做。
      猜你喜欢
      • 2019-07-13
      • 1970-01-01
      • 1970-01-01
      • 2011-03-13
      • 2012-08-09
      • 1970-01-01
      • 2021-07-31
      • 1970-01-01
      相关资源
      最近更新 更多