Borland C ++ - 多线程TCPServer问题

时间:2013-12-19 07:07:44

标签: c++ multithreading c++builder indy borland-c++

[我可能错了] TIdTCPServer Server 在Borland C ++构建器中是多线程的。它在单独的线程上处理所有客户端。这是在Borland c ++的帮助下编写的。

现在是我的问题&题。 例如,应在main(gui)线程上调用ShowMessage(String ..)方法。但正如我上面所说,TCPServer是多线程的,并在不同的线程上处理OnExecute事件。当我在OnExecute事件中使用ShowMessage方法(在与主线程不同的线程上处理)时,我得到了奇怪的结果。有时ShowMessage()按预期工作,有时它显示没有任何文字,有不同的框大小(无限长,非常长,正常等)。其他用户界面更改没有问题(更新TEdit,TMemo。现在只有ShowMessage()有问题)

我认为这个问题是调用ShowMessage()方法不是在主(gui)线程上而是在TCPServer的线程上的结果,该线程是由TIdTCPServer在内部为客户端连接创建的。 那么我该如何解决呢?

3 个答案:

答案 0 :(得分:5)

ShowMessage()显示VCL TForm,因此不是线程安全的。您必须使用TThread::Synchronize()TThread::Queue()TIdSyncTIdNotify或您选择的任何其他线程间通信机制,使ShowMessage()在主网络上运行线程。

要在工作线程中显示弹出消息,请改用Win32 API MessageBox()函数。它是线程安全的,可以在任何线程中调用而不与主线程同步。

答案 1 :(得分:3)

用户界面的所有更改都应在主线程中完成。您可以使用TThread::Queue函数在主线程中执行函数。它将消息发布到主消息队列,并在主线程处理消息时执行作为参数传递的TThreadMethod。

如果您需要将数据传递给主线程,例如要显示的消息,你必须单独执行,因为函数参数不能通过队列函数传递。

答案 2 :(得分:0)

是的,您的问题很可能与TCP无关。任何 VCL 访问必须在主线程内完成。 (不要忘记,通常从VCL包装器调用消息对话框,而不是直接通过winapi调用)

是的,我知道即使没有,它有时也能“很好”,但随后出现了这个问题:

  1. 始终是应用程序关闭/退出的例外
  2. 偶尔的应用程序挂起/异常(对于App而言致命或非致命)
  3. 偶尔会损坏VCL视觉资料(列表中缺少项目,错过事件等)
  4. 偶尔出现不可预测的行为(有时会覆盖App非VCL数据)
  5. 许多偶然的问题都是可重复的,取决于:

    • UI复杂性
    • 源代码复杂性(更多代码更常出现问题)
    • 窗口/表格数量

    还要注意内存泄漏。如果内存管理器被无效删除等破坏,VCL极不稳定......(不知道在新版本中它如何,但在bds2006中这是一个非常大的问题)

    PS。如果你只需要对话框然后使用WINAPI接口它甚至可以在线程中工作,如果你的文本数据不是VCL相关的(例如AnsiString变量访问很好,但DBGrid访问不是)