線程調用UpdateData函數出錯


在嘗試線程更新界面時,在線程中調用UpdateData(FALSE)后出現如下錯誤:

原因:

  MFC對象不支持多線程操作,不能供多個線程進程使用。子線程調用pDlg-> UpdateData(FALSE)時主線程(界面線程)會阻塞,更新必須由它完成,這樣就形成死鎖。UpdateData()函數屬於CDialog類的保護成員函數,在工作線程中不能使用UpdateData來更新主線程中的數據。更改界面的操作最好用主線程(界面線程),要想在子線程(工作線程)里執行界面線程的操作,可以通過向主線程發送消息來解決。

解決辦法:

1. 創建線程時使用AfxBeginThread創建CWinThread繼承類,參數傳遞時最好傳遞窗口句柄(主線程向子線程傳遞對象不安全),使用PostMessage或SendMessage消息傳遞函數向主窗口發送自定義消息,在主窗口中對自定義消息進行處理並更新。

創建線程:

void CEditTestDlg::OnBnClickedButton4()
{
    CWinThread* pThread;
    pThread = AfxBeginThread(SendMsgThread,this);
}

發送消息(推薦使用SendMessageTimeout):

static UINT SendMsgThread(LPVOID lpParam)
{
    CEditTestDlg *dlg = (CEditTestDlg*) lpParam;
    int i = 0;
    while (i < 100)
    {
        Sleep(20);
        i += 1;
        dlg->m_value2.Format(_T("%d"), i);
        //PostMessage(dlg->m_hWnd,WM_UPDATEDATA,FALSE,NULL);
        //SendMessage(dlg->m_hWnd,WM_UPDATEDATA,FALSE,NULL);
        SendMessageTimeout(dlg->m_hWnd, WM_UPDATEDATA, FALSE, NULL, SMTO_BLOCK, 1000, NULL);
    }
    return 0;
}

消息處理:

LRESULT CEditTestDlg::OnUpdateData(WPARAM wParam, LPARAM lParam)
{
    UpdateData(wParam);
    return 0;
}

 

2. 使用control變量或直接獲取控件指針進行更新:

dlg->m_editCtl.SetWindowText(dlg->m_value2);
dlg->GetDlgItem(IDC_EDIT2)->SetWindowText(dlg->m_value2);

3. 最簡單的辦法,將Debug改為Release正常運行。

 

 相關內容請查看:MFC添加自定義消息

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM