1. 程式人生 > >MFC 多執行緒通訊 MultiThread7例項

MFC 多執行緒通訊 MultiThread7例項

最近學習多執行緒方面的知識,網上下載的MultiThread7的原始碼,在VC6.0裡面執行沒有問提,直接從VC6.0轉到VS2005也沒有什麼問題,都可以成功執行並得到結果。                      但是,自己動手在VS2005新建工程實現相同的功能確遇到了問題。

第一個是:

errorC2440: “static_cast”:無法從“LONG (__thiscall CCalculateThread::*)(UINT,LONG)”轉換為“void(__thiscall CWinThread::* )(WPARAM,LPARAM)”

這個簡單,直接將函式afx_msg  LONG OnCalculate(UINTwParam,LONG lParam); 的返回值改為void即可編譯通過。

但是編譯通過了但是第二個問題又出來了………………

第二個是:

 當你滿以為自己搞定了,準備驗證一下結果是否正確的時候,卻又被當頭潑了一盤冷水,一個莫名其妙的錯誤把你剛才的資訊擊了個粉碎。(如圖)

記憶體不足!!!不錯,C++最怕這樣的錯誤,記憶體洩露了?指標沒有釋放?不對呀!剛點選求和按鈕就記憶體不足了?是不是電腦配置太低?鬱悶啊……………………

這個問題倒也不難解決,再認真檢查了程式裡面不存在指標不釋放的情況之後,開始尋找其它可能情況,最後發現是缺少DECLARE_DYNCREATE和IMPLEMENT_DYNCREATE巨集導致的。

具體是為什麼可以自己查一下資料。

解決辦法:

1、在CalculateThread.h

檔案的classCCalculateThread中加入DECLARE_DYNCREATE(CCalculateThread)

classCCalculateThread :public CWinThread

{

DECLARE_DYNCREATE(CCalculateThread)

…………………………

…………………………

}

2、在CalculateThread.cpp檔案中加入IMPLEMENT_DYNCREATE(CCalculateThread,CWinThread)

這下沒有問題了吧,編譯通過了,執行也不會報錯了,可以跑起來了吧!!!哈哈哈……高興的未免有點兒早了吧?結果出不來?沒錯,就是結果出不來!!!繼續努力吧您…………

這就TMD比較鬱悶了,不報錯了就是不出結果!!!剛開始考慮是自定義的兩個訊息WM_CALCULATE和 WM_DISPLAY沒有傳送成功,是哪一個呢?

通過抓鬮確定訊息WM_CALCULATE沒有傳送成功的可能性較大!!!那就搞個函式驗證一下吧:

在類CCalculateThread中加了個函式void OnCalculate2(int liujun);

voidCCalculateThread::OnCalculate2(int liujun)

{

     CStringsumStr;

     int nTmpt=0;

     for(inti=0;i<=liujun;i++)

     {

         nTmpt=nTmpt+i;

     }

     sumStr.Format(_T("%d"),nTmpt);

    //向主執行緒傳送訊息WM_DISPLAY

     ::PostMessage((HWND)(GetMainWnd()->GetSafeHwnd()),WM_DISPLAY,nTmpt,NULL);//

     return;

}

在檔案CMultiThread7Dlg.cpp中求和按鈕的訊息響應函式中直接呼叫函式OnCalculate2,咱不用訊息驅動了!!!

voidCMultiThread7Dlg::OnBnClickedSum()

{

     // TODO: 在此新增控制元件通知處理程式程式碼

     m_pCalculateThread= (CCalculateThread*)AfxBeginThread(RUNTIME_CLASS(CCalculateThread));

     m_pCalculateThread->PostThreadMessage(WM_CALCULATE,nAddend,NULL);

     CCalculateThreadTheCalculateThread;

     TheCalculateThread.OnCalculate2(nAddend);//直接呼叫函式

}

結果怎麼樣呢?

不錯,結果出來了,看來抓鬮有時候還是很好用的!!!這就說明這句沒有問題,訊息WM_DISPLAY傳送成功了。

::PostMessage((HWND)(GetMainWnd()->GetSafeHwnd()),WM_DISPLAY,nTmpt,NULL);

那就是訊息WM_CALCULATE沒有成功發出去,那就是下面這個出問題了,它失敗了!!

m_pCalculateThread->PostThreadMessage(WM_CALCULATE,nAddend,NULL);

但是,在除錯狀態跟進去也沒有跟出個所以然來!!!這下徹底抓狂了,在網上搜了一個下午沒有找到答案,倒是有幾個遇到了相同的問題,但是最終沒有給出答案!!!讓我氣憤的是,有個哥哥遇到相同的問題,到論壇上求助。大家都積極給這位老兄支招,最後這位大哥說他自己解決了,但是卻沒有說是怎麼解決的!!!把我氣的就差罵娘了,最討厭這種做法,有問題來論壇求助,解決了就自個兒偷著樂,對這種人真是無語了!!!

一時氣憤,發了點兒牢騷!!!祈求原諒中………………

  接著說,最後這個問題折騰的時間不短,但是其實挺容易解決的。

BOOL CCalculateThread::InitInstance()

{

     // TODO: 在此新增專用程式碼和/或呼叫基類

//return CWinThread::InitInstance();

     return TRUE;

}

沒有錯!!!將預設的returnCWinThread::InitInstance();換成return TRUE;就OK了!!

其實跟進去看看就會發現,函式InitInstance()屁沒有做,就是直接return FALSE;所以我們就直接

return TRUE;

原因自己查吧,也是個學習的過程!!!

希望此文能讓哪些向我一樣的初學者不在被這幾個問題折騰!!!

最後,希望大家在論壇遇到問題,如果自己解決了就給大家共享一下,大家會記著你的好的!!!