MFC中跨线程UpdateData(FALSE)报错 ASSERT FAILD问题
2014-01-03 11:21
274 查看
文章来自:http://hi.baidu.com/yu_xiyan/item/27f82bf1a1cc0813d7ff8c8c
MFC程序,在给控件关联的变量赋值后,需要调用UpdateData(FALSE)后才能更新到界面,但是有时候却报错:
断言宏失败,在wincore.cpp的如下位置:
CObject* p=NULL;
if(pMap)
{
ASSERT( (p = pMap->LookupPermanent(m_hWnd)) != NULL ||
(p = pMap->LookupTemporary(m_hWnd)) != NULL);
}
ASSERT((CWnd*)p == this); // must be us
这个问题其实是由于跨线程访问UI元素导致的,微软在MSDN中做了如下描述:
In a multi-threaded application written using MFC, you should not pass MFC objects across thread boundaries. As a general rule, a thread should access only those MFC objects that it creates. Failure to do so may cause run-time problems including assertions
or unexpected program behavior.
也就是说,MFC的UI线程是线程相关的,每个窗口的HandleMap是储存在创建UI那个线程的堆栈里面的(thread-local-storage (TLS) ),所以,你要是在另一个线程里面通过某种方式调用UI的UpdateData(FALSE)函数,他将无法正确执行。
知道了原因就好办事了,下面提供两种解决方法:
1、通过GetDlgItem(IDC_XXX)取得控件后SetWindowText()
这种方式之所以能得逞,是因为调用SetWindowText 会导致 WM_SETTEXT被发送给目标窗体,由消息机制负责处理:
ctrlDlg->GetDlgItem(IDC_EDIT19)->SetWindowText(A2W(pData));
2、自定义一个消息,将Update消息发送到UI线程,在UI线程的对话框中处理消息,自己执行UpdateData(FALSE)函数的调用。
申明:如果未加转载说明,本文即为原创文章
转载请注明:转自Roboby's Home
本文链接:MFC中跨线程UpdateData(FALSE)报错 ASSERT FAILD问题
————————————————————-
以下来自csdn
===================arthur======
在MFC中,user句柄和gdi句柄等是对应着一组对象(并不是所有句柄),它们是通过映射关系保存在一个叫做“模块线程状态”里面的,这个“模块线程状态”是属本地线程所拥有的,所以如果在其它的线程中查找句柄对应的对象指针是找不到指定的永久对象指针的,而维护这些句柄与对象指针的映射关系的,就是靠CHandleMap类型,其中楼主所说的
afxMapHWND()
是去取当前线程状态中的当前模块状态里面的当前模块线程状态中所保存的窗口句柄与其对象映射的
CHandleMap类型的指针,在这个线程中没有一次去创建这个映射的指针时,用户如果调用了afxMapHWND()那么它就返回NULL,这时ASSERT(pMap!=NULL)就会现现断言失败,在DEBUG下面当然会跳出错误了。
MFC程序,在给控件关联的变量赋值后,需要调用UpdateData(FALSE)后才能更新到界面,但是有时候却报错:
断言宏失败,在wincore.cpp的如下位置:
CObject* p=NULL;
if(pMap)
{
ASSERT( (p = pMap->LookupPermanent(m_hWnd)) != NULL ||
(p = pMap->LookupTemporary(m_hWnd)) != NULL);
}
ASSERT((CWnd*)p == this); // must be us
这个问题其实是由于跨线程访问UI元素导致的,微软在MSDN中做了如下描述:
In a multi-threaded application written using MFC, you should not pass MFC objects across thread boundaries. As a general rule, a thread should access only those MFC objects that it creates. Failure to do so may cause run-time problems including assertions
or unexpected program behavior.
也就是说,MFC的UI线程是线程相关的,每个窗口的HandleMap是储存在创建UI那个线程的堆栈里面的(thread-local-storage (TLS) ),所以,你要是在另一个线程里面通过某种方式调用UI的UpdateData(FALSE)函数,他将无法正确执行。
知道了原因就好办事了,下面提供两种解决方法:
1、通过GetDlgItem(IDC_XXX)取得控件后SetWindowText()
这种方式之所以能得逞,是因为调用SetWindowText 会导致 WM_SETTEXT被发送给目标窗体,由消息机制负责处理:
ctrlDlg->GetDlgItem(IDC_EDIT19)->SetWindowText(A2W(pData));
2、自定义一个消息,将Update消息发送到UI线程,在UI线程的对话框中处理消息,自己执行UpdateData(FALSE)函数的调用。
申明:如果未加转载说明,本文即为原创文章
转载请注明:转自Roboby's Home
本文链接:MFC中跨线程UpdateData(FALSE)报错 ASSERT FAILD问题
————————————————————-
以下来自csdn
===================arthur======
在MFC中,user句柄和gdi句柄等是对应着一组对象(并不是所有句柄),它们是通过映射关系保存在一个叫做“模块线程状态”里面的,这个“模块线程状态”是属本地线程所拥有的,所以如果在其它的线程中查找句柄对应的对象指针是找不到指定的永久对象指针的,而维护这些句柄与对象指针的映射关系的,就是靠CHandleMap类型,其中楼主所说的
afxMapHWND()
是去取当前线程状态中的当前模块状态里面的当前模块线程状态中所保存的窗口句柄与其对象映射的
CHandleMap类型的指针,在这个线程中没有一次去创建这个映射的指针时,用户如果调用了afxMapHWND()那么它就返回NULL,这时ASSERT(pMap!=NULL)就会现现断言失败,在DEBUG下面当然会跳出错误了。
相关文章推荐
- MFC中跨线程UpdateData(FALSE)报错 ASSERT FAILD问题
- mfc多线程学习运行过程中遇到ASSERT问题
- 浅谈:切换视时基于FormView的对话框属性设置与ASSERT报错的问题
- MFC控件 void DrawItem(LPDRAWITEMSTRUCT) { ASSERT(FALSE); }
- 切换视时基于FormView的对话框属性设置与ASSERT报错的问题 (Debug Assertion Failed!)
- [存档]浅谈:切换视时基于FormView的对话框属性设置与ASSERT报错的问题
- mfc关于CButtonST按钮设置不可用时 EnableWindow(FALSE) 按键图标的问题
- 切换视时基于FormView的对话框属性设置与ASSERT报错的问题 (Debug Assertion Failed!)
- 浅谈:切换视时基于FormView的对话框属性设置与ASSERT报错的问题
- mfc中关于画图操作而导致ASSERT(m_hObject == NULL);中断问题
- 解决python3 urllib中urlopen报错的问题
- [VB.NET]求教:vb.net调用MFC DLL问题
- MFC/COM调用OLE控件/ActiveX无法显示问题
- vc.net中MFC静态与动态链接问题与release方式编译
- 【MFC中解决滚轮滚动一次的值过大的问题】
- 解决faster-rcnn中训练时assert(boxes[:,2]>=boxes[:,0]).all()的问题
- 在新复制的MFC Visual C++项目中不能自动生成代码问题的解决
- Unity3D控制人物移动跳跃,处理CharacterController的isGrounded总是返回false问题
- 项目报错:打开文件过多,数据库连接失败等资源问题
- Android开发入门常见问题:模拟器启动及Eclipse报错