在開發聊天程式用戶端的過程中,我碰到了一個問題:當運作用戶端成後,打開任務管理器,顯示程式未相應。我就想是什麼原因導緻我的程式未響應呢?是我的程式裡面有bug?
我上網查了一下,有人說可能程式本身就有bug,有人說有可能程式裡面有while無限循環。我的感覺是可能是第二種情況,因為我的程式裡面為了和伺服器進行連接配接,建立了繪畫套接字,而是以從伺服器recv資料,我們都知道recv在不進行任何設定的情況下是阻塞函數,它會一直等待對方發送的資料。而确實我有這樣的一個句子,while(ERROR_SOCKET!=recv(....)),是以我想問題可能是出在這裡吧。但是,我想在套接字程式設計裡面必須要這樣才能不停地接收對方傳送過來的資料,再說我也看過有關套接字程式設計的例子程式,而那些程式怎麼就沒有說是“未響應”呢?
直覺告訴我,問題可能不在這裡。然後我就想調用這個接收資料的函數是什麼呢?一看,原來是MFC的消息相應函數,順着這個東西我就想,程式未響應的最直接的表現就是:當程式運作起來以後,你再去點選UI界面,UI根本不響應你的任何輸入操作。按照道理,windows程式會時時監控有什麼外部操作,進而根據這些外部消息進行處理,現在不處理了,說明什麼?并且我們知道消息處理是同步的,也就是說每一次隻處理一個消息。我終于明白了,肯定是在消息處理函數中我調用了接收資料函數,而在這個函數中又調用了阻塞函數recv,recv一直處于阻塞等待狀态,是以函數沒有傳回,消息處理函數也沒有傳回,是以windows不能再處理任何對UI的操作。
有這個問題我想到了本該很清楚的一個道理,那就是将UI與你的設計邏輯分開。确實是這樣的,UI就是UI,它在處理完事件之後應該立即傳回,除非是一些特殊的用法。這也是大部分項目中,有專門搞UI設計的,有專門搞邏輯設計的原因吧。
最後,處理我的這類問題的一個最簡單的方法就是,建立一個接收資料的線程,有這個線程專門執行接受任務,這樣消息處理在主線程中,就不會出現我的那種錯誤了。