螺纹

2015-06-16 229 views
1

this thread继印TCP客户端,我想作一个C++ Builder的XE5应用:螺纹

  • 一种主要形式
  • 一个TIdTCPClient
  • 一个为TIdTCPClientTThread“ s连接,打开插座,发送请求,然后监听多个响应无限期
  • 行动插座上发生将导致主窗体上更新

我一直找不到任何例子;从Indy Demos页面链接的例子都不会在客户端使用任何线程,就我所见。

我的问题是:

  • 如若TIdTCPClient是主要的形式(如设计时间成分),或者它应该是线程类的成员变量?
  • 在由TIdTCPClient触发的事件中,事件处理程序(它是我主窗体的成员函数)中的代码是否需要同步?
  • 对于主VCL线程和客户端线程在TIdTCPClient对象上进行函数调用是否安全?

目前我在主窗体上对每个事件做出响应,并响应接收套接字上的数据。此刻,我的代码充满了临时变量和存根函数,因为Synchronize需要关闭void(void),并且它是相当意大利面条。所以我想知道我是否采取了根本错误的做法。

回答

1

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

两者都可以正常工作。最重要的是,你叫Connect()和其他I/O方法在工作线程(其Execute()方法中)的情况下。

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

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

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

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

此刻我的代码充满了临时变量和存根函数,因为Synchronize需要void(void)闭包,并且它是相当意大利面。

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

#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; 
    //... 
} 
+0

TIdSync没有组件,但我在找到它。看起来它只适用于TIdThread(目前我正在使用TThread),所以我想我应该尝试根据其API文档找出它们的工作原理。 –

+0

不,“TIdSync”不是组件,只是一个类。不,你不需要'TIdThread'来使用它。在XE5中,它只是静态'TThread :: Synchronize()'方法的一个包装。在'IdSync.hpp'中根本不应该引用'TIdThread'。对于CB2005之前的C++ Builder版本,它可以,但是您仍然可以在不使用TIdThread的情况下使用TIdSync(它只是在内部创建一个用于自己使用)。 –

+0

谢谢你 –