我对Winforms中的消息循环如何工作感到困惑。我正在Windows窗体上工作,我知道何时调用Application.Run(myform)
,所以它将创建一个消息队列和消息循环,然后显示我的Form并开始在消息队列中检索消息以进行调度。
我读了一些主题,但仍然不了解消息循环UI Thread both running message pump AND executing code?和How does the message loop use threads?在幕后的工作方式
我的问题是:消息循环是否将在UI线程上运行。如果是,为什么不阻止UI线程?
如果问题不清楚,请告诉我,对不起,因为我的英语不好。
最佳答案
可以使用以下示例代码大致解释消息循环:
Message message;
while (PeekMessage(out message))
ProcessMessage(messae);
是的,这“阻塞”了线程。线程将始终等待消息出现(消息准备就绪时,PeekMessage应该返回)或正在处理消息。
重要的是要知道,这是不会阻碍UI的魔力。 UI需要响应的任何内容均作为消息处理。
非常重要的重要部分是,为了避免阻塞UI,无论ProcessMessage为处理一条消息所做的任何操作,都不应花费太长时间。
如果用户单击按钮,则将其作为消息处理。作为处理该消息的一部分,将调用事件处理程序。如果该事件处理程序开始执行冗长的操作,则您不会返回到消息循环,因此它会在您的按钮单击事件处理程序运行时停止处理消息。
因此,是的,消息循环在UI线程上运行。是的,它也阻止了UI线程,但是它一直运行的事实意味着它没有阻止UI。
受评论的启发,我认为我应该发布一个类比解释循环为什么起作用。
想一想本地的熟食店供应食物。有些食物是现成的,只需要卖给消费者,有些食物必须按需准备。
此Deli中发生了几种典型的操作:
现在,考虑一个只有1个人在 table 后面的熟食店。
此人为每个消费者执行这三个操作。显然,如果一个消费者订购必须在那时和那里准备好的食物,则其余的消费者将不得不等待。
另一方面,如果可以将这些订单下达给接受订单的员工的厨师或厨师,那么订单将更快地处理。
在Windows中,消息循环是此Order-take-employee,并且只有他。
作为处理订单(消息)的一部分,此人将不得不去检查其他人,然后等待,然后再将食物(结果)带回消费者手中。因此,任何冗长的处理都会减慢该队列的处理速度。
另一方面,如果那个“其他人”简单地说,您回到队列,告诉消费者他准备好食物时就会得到食物,那么即使有人正在等待他们的食物,队列也会移动。食物。
这是为了保持UI响应能力而引入的典型线程或异步处理。