先說說WaitForSingleObject的功能,如果wait的handle不是屬於被SetEvent的,他就會進入阻塞狀態,
直到設定的timeout跳出,或是等待時間參數又設定成INFINITE,則一直等到handle被SetEvent為止。這就是上一篇說的同步作法。
那問題在哪邊呢?就在於阻塞狀態,他會將訊息也一起塞著了,如果這個是寫在需要訊息傳遞的,比方說對話框或是主Process,
那.....當進入WaitForSingleObject時,點擊「x」想關閉視窗,或是按下OK要跳出時,完全沒反應了。再不然就是直接crash,塞太多message了。
所以有另一種方式可以避免,在等待Event的同時,還繼續響應message,使不會塞著的,就是MsgWaitForMultipleObjects。用郵差的例子,不知恰不恰當。假設你的Thread是郵差,郵差的基本任務就是接受信件(GetMessage),然後處理這些信(DispatchMessage)。一般而言會不斷有信(SendMessage)寄到郵筒(Message Queue),這時後郵差可能有三個動作:
- 隨時看郵筒有沒有信進來(PeekMessage),從郵筒拿走信(PM_REMOVE),再把信拿回郵局處理(DispatchMessage)
- 或是懶惰不處理,看一看就把信留在郵筒裡(PM_NOREMOVE),等想處理的時候,再去從郵筒拿信(GetMessage)
- 從郵筒拿完如果沒有處理(No DispatchMessage),那就等於把信丟掉,永遠消失了
//看message queue中有無message,有的話移除。如果後面不是接著寫DispatchMessage, //那這邊要寫PM_NOREMOVE,不然訊息就直接沒處理丟棄了。 while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){ if(msg.message == WM_QUIT) return; DispatchMessage(&msg);//分派訊息到窗口的訊息處理函數WindowProc }不過這一位高手做了測試,其實可以用固定時間的WaitForSingleObject來代替MsgWaitForMultipleObjects,並且循環等待,訊息也不會被卡住的。
0 意見:
張貼留言