【问题标题】:Indy TCP client in thread线程中的 Indy TCP 客户端
【发布时间】:2015-06-16 15:19:20
【问题描述】:

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

  • 主要形式
  • TIdTCPClient
  • TThread 用于该 TIdTCPClient 的连接,它打开套接字,发送请求,然后无限期地监听多个响应
  • 在套接字上发生的操作将导致主窗体上的更新

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

我的问题是:

  • TIdTCPClient 应该在主窗体上(作为设计时组件),还是应该是线程类的成员变量?
  • 在 TIdTCPClient 触发的事件中,事件处理程序(我的主窗体的成员函数)中的代码是否需要同步?
  • 主 VCL 线程和客户端线程对 TIdTCPClient 对象进行函数调用是否安全?

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

【问题讨论】:

    标签: multithreading c++builder indy vcl


    【解决方案1】:

    TIdTCPClient 应该在主窗体上(作为设计时组件),还是应该是线程类的成员变量?

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

    在 TIdTCPClient 触发的事件中,事件处理程序(我的主窗体的成员函数)中的代码是否需要同步?

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

    主 VCL 线程和客户端线程在 TIdTCPClient 对象上进行函数调用是否安全?

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

    目前我的代码充满了临时变量和存根函数,因为 Synchronize 需要一个 void(void) 闭包,而且它是意大利面条。

    您可以使用 Indy 的 TIdSync/TIdNotify 类来帮助您更好地组织意大利面条式代码。例如,从TIdSync 派生一个类,将变量移入其中,并覆盖其虚拟DoSynchronize() 方法以根据需要调用您的Form 方法。然后你可以创建你的类的一个实例,如果需要的话填充它的变量,调用它的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;
        //...
    }
    

    【讨论】:

    • TIdSync 没有组件,但我在 中找到了它。看起来它只适用于 TIdThread(目前我正在使用 TThread)所以我想我应该尝试根据他们的 API 文档弄清楚它们是如何工作的
    • 不,TIdSync 不是一个组件,只是一个类。不,你不需要TIdThread 来使用它。在 XE5 中,它只是静态 TThread::Synchronize() 方法的包装器。在IdSync.hpp 中根本不应该有对TIdThread 的引用。对于 CB2005 之前的 C++Builder 版本,可以,但您仍然可以使用 TIdSync 而不使用 TIdThread(它只是在内部创建一个供自己使用)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-26
    • 2016-12-06
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多