MFC中跨线程UpdateData(FALSE)报错 ASSERT FAILD问题

转载 2014年01月03日 11:21:58

文章来自: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下面当然会跳出错误了。

线程中使用UpdateData出错解决方法

原文链接:http://www.cnblogs.com/lebronjames/archive/2011/02/16/1956029.html 最近写一个程序,需要在自己创建...
  • saiolive
  • saiolive
  • 2016年05月19日 15:05
  • 1705

VC++线程中不能用updatedata()的解决办法

本文转自http://hi.baidu.com/xiaoqiangswust/item/f9ea3c8f296d9bdf5f0ec1e7 线程中不能用updatedata()的解决办法 用...
  • daoyue
  • daoyue
  • 2013年06月26日 09:44
  • 761

工作线程中调用UI线程创建的窗口的UpdateData会导致Assert的问题及解决办法(ZZ)

最近写了个代码,在UI线程中创建了一个窗口,然后在工作线程中修改了这个窗口中的一些数据,然后想用UpdateData(FALSE)来更新窗口的内容,结果在Debug版本下面就出现了Assert报错,说...
  • faithmy509
  • faithmy509
  • 2010年03月27日 14:34
  • 2020

MFC中多线程中updatedata()遇到Debug Assertion Failed 错误

最近在一个统计目录中文本文件 中文词频的软件的时候,要用到多线程的方法,结果总是出现bug Debug Assertion Failed! file:wincore.cpp  line:895...
  • lilien1010
  • lilien1010
  • 2012年04月21日 18:46
  • 5359

Visual C++ 6.0 常见断言错误总结

断言 所在函数 具体位置 意义 ASSERT(m_hWnd==NULL) CWnd::Attach() WINCORE.CPP文件中的第320行 这个断言通常可能是由于试图把一个...
  • liyun422828
  • liyun422828
  • 2011年11月01日 21:16
  • 1154

MFC中,执行程序出现断言错误

UpdateData(true);       //true是把对话框的内容赋值给变量,false是把变量的内容显示给对话框 MFC中跨线程UpdateData(FALSE)报错 ASSERT FA...
  • feilong911hao
  • feilong911hao
  • 2014年03月25日 15:29
  • 858

assert(pMap != NULL)错误的解决办法

最近在使用mfc进行多线程程序开发的过程中,由于需要实时在某个控件上进行数据更新操作,因此将某个控件进行了变量绑定,通过改变变量进行数据更新操作,但是每次都显示错误导致程序不能运行,具体指向winco...
  • sjhuangx
  • sjhuangx
  • 2015年06月07日 10:43
  • 1779

线程访问窗口资源的问题

在开个线程时常为所开的线程传入个窗口参数 (cwnd),,,这里里面有个很大的隐患就是当做CWnd::AssertValid()检查,就会遇到断言失败。具体原因在于MFC管理窗口的机制。MFC有个窗口...
  • WhyGoSoFar
  • WhyGoSoFar
  • 2008年04月10日 22:41
  • 4537

afxMapHWND(保存CWnd类和HWND之间的映射)

转自http://q1q2q3q4q5q6ln.blog.163.com/blog/static/500794332010102863012926/ 在Windows体系中,很多对象都是以句柄的...
  • T_W_S
  • T_W_S
  • 2012年11月20日 22:32
  • 1527

SubClassWindow详解 子类化机制

许多Windows程序员都是跳过SDK直接进行RAD开发工具[或VC,我想VC应不属于RAD]的学习,有些人可能对子类化机制比较陌生。 我们先看看什么是Windows的子类化。 Windows给我们...
  • harvic880925
  • harvic880925
  • 2013年05月20日 15:25
  • 2593
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:MFC中跨线程UpdateData(FALSE)报错 ASSERT FAILD问题
举报原因:
原因补充:

(最多只允许输入30个字)