2011-03-22 103 views
0

一個單獨的線程創建一個TidTCPClient和一個TTimer。 TTimer設置爲3秒,如果TCPClient未連接,則它調用TCPClient.Connect。
如果沒有要連接的服務器,則會每3秒嘗試連接一次。爲什麼單獨線程中的TidTCPClient阻塞主線程?

主線程(UI)什麼都不做,但如果我用鼠標抓住窗口並緩慢地在屏幕上移動它,它會每3秒鐘停留約2秒鐘,然後跳轉到鼠標光標位置並再次跟隨鼠標,直到下一次連接嘗試發生。

換句話說,當TCPClient嘗試連接時,主線程似乎被阻塞。

爲什麼會發生這種情況,即使TCPClient位於單獨的線程中?

+1

組件在線程中不存在,它們存在於內存中。代碼在您調用它的線程中執行。 – 2011-03-22 17:20:56

回答

6

您的TTimer通過接收WM_TIMER消息來工作;這些消息在VCL線程中使用VCL的主消息泵進行分派。在3秒過期後,您的TTimer.OnTimer事件在主線程中運行,因此Connect的調用將在主VCL線程中運行。

由於您沒有穿線而被阻擋!

+1

+1「for you because not you threading! – jachguate 2011-03-22 17:02:58

+1

只有在主線程上下文中創建了'TTimer',例如在線程的構造函數中,纔會出現這種情況。有一個TTimer在一個線程中運行,它需要在線程的Execute()方法內創建,然後該線程需要自己的消息循環,以便正確調用WM_TIMER消息。不是線程安全的(因爲它在內部使用'AllocateHWnd()'),所以你應該直接使用'SetTimer()',或者通過''TimeSetEvent()''通過多媒體定時器'CreateWaitableTimer() ,甚至只是一個手動睡眠循環。 – 2011-03-22 22:39:20

+0

是的,計時器是在Thread的構造函數中創建的。感謝您的解釋 – Holgerwa 2011-03-23 13:55:32