2009-10-16 31 views
3

我正在開發一個多線程的win32 MFC應用程序。我們正在渲染地圖並將其顯示在用戶界面的窗格中,以及頂部的自定義渲染對象。渲染速度很慢(〜800 ms),這發生在用戶界面線程上。ASSERT在CDC SelectObject()調用失敗 - 我可以嘗試什麼?

我試圖渲染移動到它自己的線程,這樣的菜單仍然活潑,而其他的渲染可以在後臺運行依舊。 Draw線程將使用自己的CDC持續渲染。 UI線程將調用重繪函數,該函數鎖定互斥鎖,並獲取CBitmap的最後一個快照,並使用UI的CDC進行繪製。每個使用Draw線程CD C的位置都被互斥鎖鎖定。

我所看到的是線程建立通過CreatCompatibleBitmapCBitmap,然後嘗試選擇新的CBitmap對象插入到拉線的CDC

this->m_canvas.CreateCompatibleDC(&compatibleDC); 
this->m_bitmap = new CBitmap(); 
this->m_bitmap->CreateCompatibleBitmap(&compatibleDC, m_width, m_height); 

m_oldBitmap = this->m_canvas.SelectObject(m_bitmap); 

在這一點上,存在CGdiObject調試ASSERT失敗:: FromHandle()。

CGdiObject* PASCAL CGdiObject::FromHandle(HGDIOBJ h) 
{ 
    CHandleMap* pMap = afxMapHGDIOBJ(TRUE); //create map if not exist 
    ASSERT(pMap != NULL); 
    CGdiObject* pObject = (CGdiObject*)pMap->FromHandle(h); 
    ASSERT(pObject == NULL || pObject->m_hObject == h); 
    return pObject; 
} 

第二ASSERT失敗,因爲m_hObject不通過手柄相匹配。基本上,MFC走的是手柄,並做了查找,以得到一個CBitmap對象莫名其妙地不匹配CBitmap這是剛創建。

這聽起來對任何人都很熟悉嗎?可能發生什麼情況導致FromHandle方法返回錯誤的對象?對於Draw線程創建CDC的方式是否存在根本缺陷,然後重複使用它?有什麼方法可以幫助調試/修復這個問題嗎?

+0

這絕對是奇怪的:由您在CGdiObject是時間:: FromHandle(),我們正在處理來自::選擇對象()的返回值,這不是明顯的怎麼會出問題。斷言發生時,pObject看起來像一個有效的對象嗎? – DavidK 2009-10-16 17:28:52

+0

是的。 pObject是有效的,並且是一個CBitmap ...但不是在'new Bitmap()'語句中構造的相同的CBitmap。 – Kieveli 2009-10-16 18:48:47

+0

每個線程都有一個句柄 - >對象查找映射......我在一個線程中創建了CBitmap,然後嘗試在另一個線程中使用它......映射中的查找失敗。 – Kieveli 2009-10-16 18:49:27

回答

2

金。手柄和對象之間的映射位於thread-local storage

在多線程環境 因爲窗口歸線程所有, MFC保持在線程中的臨時和永久性 窗口句柄地圖本地 存儲。其他 句柄映射也是如此,例如GDI對象 和設備上下文。螺紋保持 窗口句柄映射本地 存儲確保由幾個線程 對 同時訪問保護。

所以基本上,存儲句柄,然後從句柄創建一個CBitmap,以便在線程之間操作它們。

我的錯誤是在UI線程創建我的CBitmap,然後訪問來自兩個線程的CBitmap對象。

+1

heh。由於完全相同的原因,將繪製代碼移動到自己的線程中時發生了完全相同的錯誤。得到了一些很好的答案和參考,提出了一個可能有價值的類似問題; http://stackoverflow.com/questions/2287114/thread-type-for-background-drawing-to-a-bitmap-in-mfc – 2010-04-22 06:55:36

+0

你能舉一個你如何存儲句柄的例子嗎? – Vinzenz 2015-04-16 14:45:41

+0

這是MFC存儲句柄作爲CBitmap實現的一部分。如果您在尋找Handles或線程本地存儲時遇到的具體問題,請提出一個新問題以獲得更多人的幫助! – Kieveli 2015-04-17 14:12:33

相關問題