2012-06-26 29 views
4

當仍然有消息掛起時窗口被破壞時會發生什麼?已銷燬的窗口的掛起消息會發生什麼情況?

考慮以下情形:

有三個線程,A,B和C線程C-擁有一個窗口。

線程A和B使用SendMessage張貼消息到該窗口。來自A的消息首先到達。當C處理來自A的消息時,它使用DestroyWindow銷燬它的窗口。

來自線程B的消息會發生什麼?線程B對SendMessage的調用返回嗎?

這是如何在內部工作的?

回答

1

根據MSDNDestroyWindow 「[...],刷新線程消息隊列,[...]。」我不確定這是否意味着處理這些信息或傾銷它們,所以我試了一下。原來是後者:所有等待發布的消息都從隊列中刪除並被忽略。至於非排隊消息:在我的測試中,掛起的SendMessage調用返回並將最後一個錯誤設置爲ERROR_INVALID_PARAMETER - 87 (0x57)

+0

有趣,但我不會依賴這種行爲。可能存在競爭條件,即結果可能很大程度上取決於三個線程的排定順序,所以它可能在99.9%的時間內完成一件事,而另一件事則以0.1%的差別完成。 –

+0

現在我想起來了,我的觀點可能是沒有意義的;通過可能已經被銷燬的窗口句柄確實發送消息本質上是無效的? –

+0

http://stackoverflow.com/questions/7055869/are-window-handles-unique-or-do-they-ever-get-reused –

1

原則上,你打算做的事情是不安全的。線程C無法保證線程B已經發送了消息;如果窗口在線程B發送消息之前被銷燬,並且如果窗口句柄恰好在此期間被重用,則線程B可能會將消息發送到錯誤的窗口,該窗口可能位於不同的應用程序中。

最好的做法是確保所有的線程都被告知特定的窗口句柄已經變得無效之前調用DestroyWindow。

然而,實際而言,手柄的風險被在錯誤的時間重複使用是非常低的。如果提前通知其他線程不合理,您不可能因此而陷入困境。我相信kicsit在聲明消息不會最終在線程C的消息隊列中等待時是正確的,儘管文檔沒有明確地承諾這一點,據我所知。

相關問題