我一直在嘗試理解事件循環(一般不太好),並且我已經讀過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. Java發送消息線程
- 2. 將消息發送到不同線程
- 3. 發送消息到Windows GUI線程
- 4. 「PostMessage」從一個工作線程發送消息到主GUI線程
- 5. Android:從單獨線程發送的消息將obj設置爲空
- 6. 從另一個線程向對象的委託發送消息
- 7. C++線程:如何發送消息到其他長線程?
- 8. 從單獨的線程發出Toast消息
- 9. VB.NET在一個單獨的線程中發送電子郵件
- 10. 發送登錄信息到一個單獨的網站
- 11. 只發送一次消息,而不是定期發送消息
- 12. 在兩個單獨的對象之間發送消息
- 13. LinkedIn發送消息到一個連接
- 14. 發送一個xml消息到端口
- 15. android向工作線程發送消息
- 16. 將消息發送到死線程上的處理程序
- 17. 發送到UI線程的消息永遠不會到達
- 18. 從服務發送一個簡單的消息到活動
- 19. 發送點擊消息到另一個應用程序進程
- 20. 發送處理的消息到特定的線程
- 21. Java:將消息發送到多線程的JMS隊列
- 22. 發送消息或收到消息?
- 23. 發送來自兩個不同線程的TCP消息
- 24. Slack發送直接消息到SLACK上的所有消息(非羣組消息我想發送個人消息
- 25. 發送單SignalR消息給多個組
- 26. 」有一個箴言發送命令到程序「錯誤消息
- 27. 發送消息到另一個應用程序在Linux中
- 28. 發送日誌消息到遠程API
- 29. 發送消息到WCF主機進程
- 30. MSMQ發送消息到遠程隊列