在主线程和子线程之间使用TThread的“同步”或使用窗口消息进行IPC更好吗?

xet 发布于 2019-11-10 delphi 最后更新 2019-11-10 12:10 68 浏览

我用Delphi 2007编写了一个相当简单的多线程VCL gui应用程序。我在多个子线程(最多16个并发)中进行了一些处理,这些子线程需要更新我的主窗体上的网格控件(只需将字符串发送到网格)。没有任何一个子线程互相对话。 我最初的设计是调用TThread's "Synchronize"来更新当前运行线程中的网格控件窗体。不过,我明白,调用Synchronize本质上就像调用时的主线程一样执行。一次运行多达16个线程(并且大多数子线程的处理需要从<1秒到大约10秒),窗口消息会是更好的设计吗? 我已经得到它的工作,在这个点上,子线程发布一个windows消息(包含多个字符串的记录),并且主线程有一个监听器,并且在收到消息时简单地更新网格。 在这种情况下对于IPC的最佳方法有何看法?窗口消息或“同步”? 如果我使用窗口消息,你是否建议在我发布到TCriticalSection(进入和离开)块的网格中包装代码?或者我将不需要担心线程安全性,因为我正在写入主线程中的网格(尽管在窗口消息处理函数中)?

已邀请:

jalias

赞同来自:

顺便说一下,您也可以使用TThread.Queue()而不是TThread.Synchronize()Queue()是异步版本,它不会阻止调用线程: (自D8起,Queue可用)。 我更喜欢Synchronize()Queue(),因为它更容易理解(对于其他程序员)和更好的OO而不是简单的消息发送(无法控制它或能够调试它!)

jvitae

赞同来自:

内容太长未翻译

uet

赞同来自:

虽然我确信有正确的方法和错误的方式。我用两种方法编写代码,而我一直在返回的是SendMessage方法,我不知道为什么。 SendMessage vs Synchronize的使用并没有什么区别。两者的工作基本相同。我认为我继续使用SendMessage的原因是我感觉到更多的控制,但我不知道。 SendMessage例程使调用线程暂停并等待,直到目标窗口完成处理发送的消息。因此,主要应用程序线程在调用期间基本上与调用子线程同步。您不需要在Windows消息处理程序中使用关键部分。 从调用线程到主应用程序线程,数据传输基本上是一种方式。您可以在message.result中返回整数类型值,但不指向主线程中的内存对象。 由于这两个线程是“同步”的,因此该点和主应用程序线程当前被绑定响应SendMessage,那么您也不需要担心其他线程进入并同时丢弃您的数据。因此,您不必担心使用关键部分或其他类型的线程安全措施。 对于简单的事情,您可以定义单个消息(wm_threadmsg1)并使用wparam和lparam字段来回传输(整数)状态消息。对于更复杂的示例,您可以通过将其传递给lparam并将其转换回longint来传递字符串。 A-la longint(pchar(myvar))或使用pwidechar如果您使用D2009或更新版本。 如果您已经使用了Synchronize方法,那么我不会担心重新进行更改。