[我可能错了] TIdTCPServer Server 在Borland C ++构建器中是多线程的。它在单独的线程上处理所有客户端。这是在Borland c ++的帮助下编写的。
现在是我的问题&题。
例如,应在main(gui)线程上调用ShowMessage(String ..)
方法。但正如我上面所说,TCPServer是多线程的,并在不同的线程上处理OnExecute
事件。当我在OnExecute事件中使用ShowMessage方法(在与主线程不同的线程上处理)时,我得到了奇怪的结果。有时ShowMessage()
按预期工作,有时它显示没有任何文字,有不同的框大小(无限长,非常长,正常等)。其他用户界面更改没有问题(更新TEdit,TMemo。现在只有ShowMessage()
有问题)
我认为这个问题是调用ShowMessage()
方法不是在主(gui)线程上而是在TCPServer的线程上的结果,该线程是由TIdTCPServer在内部为客户端连接创建的。
那么我该如何解决呢?
答案 0 :(得分:5)
ShowMessage()
显示VCL TForm
,因此不是线程安全的。您必须使用TThread::Synchronize()
,TThread::Queue()
,TIdSync
,TIdNotify
或您选择的任何其他线程间通信机制,使ShowMessage()
在主网络上运行线程。
要在工作线程中显示弹出消息,请改用Win32 API MessageBox()
函数。它是线程安全的,可以在任何线程中调用而不与主线程同步。
答案 1 :(得分:3)
用户界面的所有更改都应在主线程中完成。您可以使用TThread::Queue函数在主线程中执行函数。它将消息发布到主消息队列,并在主线程处理消息时执行作为参数传递的TThreadMethod。
如果您需要将数据传递给主线程,例如要显示的消息,你必须单独执行,因为函数参数不能通过队列函数传递。
答案 2 :(得分:0)
是的,您的问题很可能与TCP无关。任何 VCL 访问必须在主线程内完成。 (不要忘记,通常从VCL包装器调用消息对话框,而不是直接通过winapi调用)
是的,我知道即使没有,它有时也能“很好”,但随后出现了这个问题:
许多偶然的问题都是可重复的,取决于:
还要注意内存泄漏。如果内存管理器被无效删除等破坏,VCL极不稳定......(不知道在新版本中它如何,但在bds2006中这是一个非常大的问题)
PS。如果你只需要对话框然后使用WINAPI接口它甚至可以在线程中工作,如果你的文本数据不是VCL相关的(例如AnsiString变量访问很好,但DBGrid访问不是)