2012-07-25 91 views
10

我需要一些正确的编码建议:好编码? (多消息循环)

我正在使用多个串行连接的程序。每条通信线路都有一个控制器作为抽象层。在控制器和串行端口之间插入一个协议,将数据封装在包中,准备传输。该协议负责处理失败的传送,重新发送等。 为确保GUI不会挂起,每条连接线(协议和串行端口)都在单独的线程上创建。控制器由主线程处理,因为它在GUI中具有控件。当我创建线程时,我选择在它们上创建一个消息循环(Application.Run()),因此,如果没有工作轮询缓冲区并产生结果,我只需调用线程(BeginInvoke)并使用消息循环作为缓冲区。目前这个工作很好,至今没有严重的问题。

我现在的问题是:这是“好的编码”,或者我应该使用一个while循环的轮胎,而不是轮询缓冲区?或第三件事?

我想展示代码,但到目前为止它已经有数千行代码,所以如果您需要查看代码的任何部分,请详细说明。 :)

谢谢。

回答

4

在每个线程中使用消息循环非常好, Windows针对此场景进行了优化。您有权避免轮询,但您可能希望查看其他更高效的基于事件的设计,例如准备传输包并呼吁SetEvent通知它已准备就绪的线程或信号量和线程安全队列马丁詹姆斯建议。

+0

不是,不。 WM_COPYDATA适用于进程之间的通信。使用它在一个进程内的线程间通信毫无意义。只需通过指针传递缓冲区/ blob /任何对象就简单多了,例如。通过将* Buffer转换为消息。lParam,PostMessage()并在“另一端”回退。 – 2012-07-25 08:27:25

+0

Windows消息队列已针对通信TO GUI线程进行了优化。从GUI线程到非GUI工作线程的通信不是最佳的。即使是一个简单的基于信号量的,非优化的生产者 - 消费者队列,其速度比WMQ快四倍。在大多数应用中,P-C队列性能通常不是问题。 – 2012-07-25 08:32:23

+0

我同意这两点。我将编辑出WM_COPYDATA;我没有清楚地思考。关于消息队列,这是一个广义的基于事件的解决方案。根据他的应用程序的要求,其他模型可能会更好。 – tenfour 2012-07-25 08:38:25

1

我不是100%肯定,你在做什么,但在这里,以“填补”了一下它听起来并不坏:)

当你的应用程序处于空闲状态,(无通讯),是CPU使用0%?

您的应用没有睡眠(0)/睡眠(1)或类似的轮询循环吗?

它的延迟合理吗?

如果答案是三个“YES”,你应该罚款:)

有几个,(很少!),情况轮询结果等是一个好主意,(例如,当。线程中的事件发生频率非常高,以致于向GUI发送每个进度事件都会使其不堪重负),但大多数情况下,这只是糟糕的设计。

+0

这个程序的目的是控制1-4个(迄今为止)框,每个包含一个Arduino。每个Arduino都连接到模拟器系统的数字I/O。并行模拟器系统需要一个盒子。模拟器。模拟器是我工作的公司的研发部分。 Windows程序具有在运行时重新编程Arduino引脚的易用性,以及读/写引脚的高/低状态。 – Anders 2012-07-25 09:32:10

+0

Triple YES从这里..我试图改变代码为缓冲区轮询,与thread.yields如果没有数据,并使程序缺乏一点,所以我想我很好,消息循环:) – Anders 2012-07-25 09:37:28

+0

嗯,我可能已经使用了稍微不同的队列等,但如果你的应用程序足够高效,响应迅速,不会崩溃,谁在乎:)) – 2012-07-26 08:38:15