C++ 在CDC SelectObject()调用中断言失败-我可以尝试什么?

C++ 在CDC SelectObject()调用中断言失败-我可以尝试什么?,c++,mfc,assert,C++,Mfc,Assert,我正在开发一个多线程的win32 MFC应用程序。我们正在渲染地图,并将其显示在用户界面的窗格中,以及顶部的自定义渲染对象。渲染速度很慢(~800毫秒),这发生在用户界面线程上 我正在尝试将渲染移动到它自己的线程上,以便菜单仍然保持快速,而另一个渲染仍然可以在后台运行。绘制线程将使用自己的CDC持续渲染。UI线程将调用重画函数,该函数锁定互斥锁,并获取CBitmap的最后一个快照,并使用UI的CDC绘制它。使用绘图线程的CDC的每个位置都被互斥锁锁定 我看到的是线程通过createcompati

我正在开发一个多线程的win32 MFC应用程序。我们正在渲染地图,并将其显示在用户界面的窗格中,以及顶部的自定义渲染对象。渲染速度很慢(~800毫秒),这发生在用户界面线程上

我正在尝试将渲染移动到它自己的线程上,以便菜单仍然保持快速,而另一个渲染仍然可以在后台运行。绘制线程将使用自己的CDC持续渲染。UI线程将调用重画函数,该函数锁定互斥锁,并获取
CBitmap
的最后一个快照,并使用UI的
CDC
绘制它。使用绘图线程的
CD
C的每个位置都被互斥锁锁定

我看到的是线程通过
createcompatiblebitmap
创建一个新的
CBitmap
,然后尝试将新的
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
失败,因为
mu hObject
与传入的句柄不匹配。基本上,MFC正在获取句柄,并进行查找以获得与刚刚创建的
CBitmap
对象不匹配的
CBitmap


这听起来有人熟悉吗?什么情况会导致
FromHandle
方法返回错误的对象?我为Draw线程创建
CDC
,然后反复使用它的方式是否存在根本缺陷?有什么方法可以帮助调试/修复此问题吗?

Golden。控制柄和对象之间的映射在中

在多线程环境中 因为窗口属于线程, MFC保留临时和永久文件 线程本地中的窗口句柄映射 存储其他国家也是如此 像GDI对象那样处理贴图 和设备上下文。保持 线程本地中的窗口句柄映射 存储可确保免受损坏 多用户同时访问 线程

因此,基本上,存储句柄,然后从句柄创建CBitmap,以便在线程之间操作它们


我的错误是在UI线程中创建了我的CBitmap,然后从两个线程访问CBitmap对象。

这绝对是奇怪的:当您在CGdiObject::FromHandle()中时,我们正在处理来自::SelectObject()的返回值,不清楚这会如何出错。当断言发生时,POObject看起来像有效对象吗?是的。pObject有效,并且CBitmap。。。但不是在“new Bitmap()”语句中构造的同一个CBitmap。每个线程都有一个句柄->对象查找映射。。。我在一个线程中创建CBitmap,然后在另一个线程中尝试使用它。。。地图中的查找失败。嘿嘿。出于完全相同的原因,在将绘图代码移动到自己的线程中时犯了完全相同的错误。得到了一些很好的答案和参考资料,提出了一个可能有价值的类似问题;您能举一个如何存储句柄的例子吗?MFC将句柄存储为CBitmap实现的一部分。如果在句柄或线程本地存储中您需要一些特定的东西,请提出一个新问题,让更多的人来帮助您!
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;
}