回答
這是我拉過一個線程的隊列中的消息:
while GetMessage(Msg, 0, 0, 0) and not Terminated do begin
Try
TranslateMessage(Msg);
DispatchMessage(Msg);
Except
Application.HandleException(Self);
End;
end;
使用Application.ProcessMessages
將拉動調用線程的隊列中的消息。但在消息循環中使用它並不合適,因爲它不會阻塞。這就是爲什麼你使用GetMessage
。它會阻止隊列是否爲空。並且Application.ProcessMessages
也稱其他TApplication
方法不被設計爲線程安全。所以有很多理由不會從主線程以外的線程調用它。
當你需要終止線程,那麼我這樣做:
Terminate;
PostThreadMessage(ThreadID, WM_NULL, 0, 0);
//wake the thread so that it can notice that it has terminated
這一切都不是OTL具體。此代碼全部用於生活在TThread
後代。但是,這些想法是可以轉讓的。
在註釋中,您指出要運行繁忙的非阻塞消息循環。你會使用PeekMessage
。
while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do begin
Try
TranslateMessage(Msg);
DispatchMessage(Msg);
Except
Application.HandleException(Self);
End;
end;
您可以構建一個類似於Application.Run中的循環。
您可以致電PeekMessage
,它檢查消息是否可用。 PeekMessage檢查當前線程的消息隊列,因此如果您在線程中使用它,它會檢查線程的消息隊列(可以使用PostThreadMessage向其發送消息)。
而不是PeekMessage,您還可以使用GetMessage
,它等待,直到收到一條消息。 GetMessage
返回0
返回false
。 *)
當它得到一個WM_QUIT
消息,這也是終止消息循環的信號。之後再次調用GetMessage是很冒險的,因爲它可能不會收到其他消息,並且可能會阻止您的應用程序正確關閉,因爲它阻塞了。
Application.ProcessMessages確實不是很安全,因爲它會執行很多特定於主線程的額外功能。一方面,一旦消息隊列爲空,它就會觸發Application.OnIdle,這意味着它在線程消息隊列爲空時(線程消息隊列爲空)調用(問題1),並且不允許任何VCL在事件中的交互。
* )關於GetMessage的返回值:我注意到Delphi實現了GetMessage作爲返回LongBool。但是,實際返回值是一個整數。它在WM_QUIT的情況下返回0,在發生錯誤時返回-1,在其他情況下返回非零。 Microsoft states:
因爲返回值可以是零,零,或-1,避免像 驗證碼:
while (GetMessage(lpMsg, hWnd, 0, 0)) ...
不幸的是,你必須根據不同的別名導入的GetMessage到正確使用它。
而不是重新導入,您可以只輸入GetMessage的結果。 –
- 1. Python - 線程內的線程 - kosher?
- 2. 線程內線程的優先級
- 3. 其他線程內的輔助線程
- 4. 進程內的線程
- 5. 在線程內
- 6. ObjectAnimator內線程
- 7. C++ boost ::線程,如何啓動線程內的線程
- 8. 線程中的Perl內存泄漏(線程不釋放內存)
- 9. 用戶線程v.s.內核線程
- 10. Qt內部線程
- 11. 線程vs內核
- 12. CUDA線程內環
- 13. Task.Delay內線程C#
- 14. 線程和內核
- 15. 用於Windows編程使用直接Windows API我應該使用MessageLoop?
- 16. Android - 線程內的BroadcastReceiver
- 17. 調用線程內的MessageBox
- 18. 片段內的線程
- 19. 線程內的遞歸
- 20. 工作線程內的UpdateAllViews()?
- 21. 線程的內存問題
- 22. UITableViewCell內的後臺線程
- 23. 線程內調用協程
- 24. 從線程單線程單元線程索賠資源/內存
- 25. 應用程序內的多個線程
- 26. 進程的線程級內存消耗
- 27. 服務中的線程或線程內的服務?
- 28. Android的啓發(一個線程內的線程)
- 29. 在while循環中的另一個線程內的線程
- 30. 取消線程本身內的異步線程
這看起來很複雜。它可以放在一個程序中嗎? 像這樣:「while IHTMLDocument2.readyState <>'complete'do MessageLoop;」 –
這將是一個繁忙的循環,有點不同。我的更新顯示瞭如何用'PeekMessage'做到這一點。在理想的世界中,你不會這麼做。繁忙的循環無用地消耗CPU週期。在理想的世界中,您會收到通知說您的文檔已準備就緒。 –
@DavidHeffernan看起來'而GetMessage'不是推薦的方式? https://msdn.microsoft.com/en-us/library/windows/desktop/ms644936(v=vs.85).aspx – SOUser