我正在研究多线程win32 MFC应用程序。我们正在渲染 map ,并将其与自定义渲染的对象一起显示在用户界面的 Pane 中。呈现速度很慢(约800毫秒),这是在用户界面线程上发生的。
我试图将渲染移到其自己的线程上,以便菜单仍然保持活泼,而其他渲染仍可以在后台运行。 Draw线程将使用其自己的CDC连续渲染。 UI线程将调用重绘函数,该函数将锁定互斥锁,并获取CBitmap
的最后一个快照,并使用UI的CDC
对其进行绘制。互斥锁锁定了使用绘图线程的CD
C的每个位置。
我看到的是该线程通过CBitmap
创建新的CreatCompatibleBitmap
,然后尝试在Draw线程的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::FromHandle()中出现调试ASSERT失败。
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
并一遍又一遍地重复使用的方式是否存在根本缺陷?有什么方法可以帮助我调试/修复此问题? 最佳答案
金的。句柄和对象之间的映射在thread-local storage中。
因此,基本上,存储该句柄,然后从该句柄创建一个CBitmap以便在线程之间操纵它们。
我的错误是在UI线程中创建了我的CBitmap,然后从两个线程访问CBitmap对象。
关于c++ - ASSERT在CDC SelectObject()调用上失败-我可以尝试什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1579154/