我一直在尝试理解事件循环(一般不太好),并且我已经读过Windows消息循环是单线程的。如果是这样,Application.DoEvents如何工作?事件循环没有一次处理一条消息,并且在处理每个消息/事件时阻塞?消息事件循环是否需要存在于与处理Application.DoEvents消息的消息不同的线程上?如果有独立的线程,我们称之为“主”线程的是哪一个?我相信我错过了一些非常简单的东西,我只是不知道它是什么。是Application.DoEvents发送消息到一个单独的线程?
回答
我花了一整天的时间搞清楚这一点(如果我说的是错的,请评论,让我知道,所以我可以纠正它)。我实际上必须构建一个旧的Win32应用程序并自己创建消息循环(我是一个非常持久的SOB)。因此,有一个叫WinMain函数是启动消息循环,看起来像这样:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
有关的GetMessage事情()是它阻止,直到一个消息是在消息队列中可用。如果你运行一个Windowed应用程序,并且坐在那里查看窗口(不要导致任何将消息发送到队列的动作),主线程(创建窗口的线程)在GetMessage() 。现在,当一条消息发布时,我们输入while循环(即如果消息不是0,则退出)。 DispatchMessage()是这里有趣的功能。这个函数最终会导致(在.NET中)EventHandler的控件和执行引发事件。我感到困惑的是,如果调用堆栈是GetMessage()/ DispatchMessage()/.../ EventHandler,那么Application.DoEvents()如何处理消息呢?那很简单。在Win32中的DoEvents是这样的:
void DoEvents()
{
MSG msg;
HACCEL hAccelTable;
hAccelTable = LoadAccelerators(hInst, MAKEINTRESOURCE(IDC_TESTWIN32));
// Main message loop:
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE) != 0)
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
所以的DoEvents()实际上启动另一个循环来处理事件,而在最初的消息循环的DispatchMessage函数()内! 关键的区别在于,不使用GetMessage(),直到队列中有消息时才阻塞,我们使用PeekMessage()返回0,并在队列中不再有任何消息时存在循环。
那么如果我们点击一个按钮两次,并且在该按钮的EventHandler中我们有一个DoEvents()调用呢?初始事件循环将处理第一次点击并触发事件。当EventHandler正在执行时,在DoEvents()调用中,事件将被再次触发,EventHandler将再次进入(有点像递归调用)。太可怕了!
所以最后,一切都发生在一个单独的线程中,并且DoEvents()实际上会阻塞,直到所有的消息都被处理并返回。现在我要睡上几天了。
- 1. 发送消息到Windows GUI线程
- 2. 将消息发送到不同线程
- 3. “PostMessage”从一个工作线程发送消息到主GUI线程
- 4. Android:从单独线程发送的消息将obj设置为空
- 5. 从另一个线程向对象的委托发送消息
- 6. 从单独的线程发出Toast消息
- 7. 只发送一次消息,而不是定期发送消息
- 8. 在两个单独的对象之间发送消息
- 9. LinkedIn发送消息到一个连接
- 10. android向工作线程发送消息
- 11. 发送到UI线程的消息永远不会到达
- 12. 发送点击消息到另一个应用程序进程
- 13. Java:将消息发送到多线程的JMS队列
- 14. 发送来自两个不同线程的TCP消息
- 15. Slack发送直接消息到SLACK上的所有消息(非群组消息我想发送个人消息
- 16. 发送单SignalR消息给多个组
- 17. 发送消息到WCF主机进程
- 18. MSMQ发送消息到远程队列
- 19. NServiceBus:发送第一条消息是慢
- 20. 从工作非gui线程发送消息到主窗口
- 21. Android程序发送消息
- 22. 保证多个发送线程的WCF TCP消息的顺序是否正确?
- 23. 发送作业到一个std ::线程
- 24. ,消息收到消息,但确认是由其他进程发送的?
- 25. 发送错误消息到另一页?
- 26. 发送消息到Twitter
- 27. 发送消息到对象
- 28. Facebook发送一条消息
- 29. iphone - 如何发送消息从一个对象到另一个?
- 30. 发送消息