线程中的 Indy TCP 客户端

Indy TCP client in thread

this thread 开始,我正在尝试制作一个 C++Builder XE5 应用程序:

我找不到任何例子;据我所知,从 Indy Demos 页面链接的示例都没有在其客户端中使用任何线程。

我的问题是:

目前,我在主窗体上执行操作以响应每个事件,并响应在套接字上接收数据。目前,我的代码充满了临时变量和存根函数,因为 Synchronize 需要一个 void(void) 闭包,这简直是意大利面条。所以我想知道我是否采取了根本错误的方法。

Should the TIdTCPClient be on the main form (as a design time component), or should it be a member variable of the thread class?

两者都可以。重要的是您在工作线程的上下文中调用 Connect() 和其他 I/O 方法(在其 Execute() 方法内)。

In the events fired by the TIdTCPClient , does the code in the event handlers (which are member functions of my main form) need to be Synchronized?

是,如果他们正在访问 UI 控件或其他必须保护的共享数据。

Is it safe for both the main VCL thread and the client thread to make function calls on the TIdTCPClient object?

这取决于特定的调用(例如,从主线程发送出站数据,同时在工作线程中读取入站数据,至少在客户端连接时),但我不建议您依赖它。您应该只在工作线程中保留所有与客户端相关的操作。

At the moment my code is full of temporary variables and stub functions because Synchronize requires a void(void) closure and it is quite spaghetti.

您可以使用 Indy 的 TIdSync/TIdNotify classes 来帮助您更好地组织意大利面条代码。例如,从 TIdSync 派生一个 class,将您的变量移入其中,并覆盖其虚拟 DoSynchronize() 方法以根据需要调用您的 Form 方法。然后你可以创建你的实例 class,如果需要填充它的变量,调用它的 Synchronize() 方法,如果需要读取它的变量,然后释放它。

#include <IdSync.hpp>

class TMySync : public TIdSync
{
protected:
    virtual void __fastcall DoSynchronize();
public:
    // variables...
};

void __fastcall TMySync::DoSynchronize()
{
    // call Form methods, use variables as needed...
}

void __fastcall TMyThread::Execute()
{
    //...
    TMySync *sync = new TMySync;
    // set variables as needed...
    sync->Synchronize();
    // read variables as needed...
    delete sync;
    //...
}