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

[入库:2005年8月18日] [更新:2007年3月24日]

本文简介:选择自 lsaturn 的 blog

    最近写了个代码,在ui线程中创建了一个窗口,然后在工作线程中修改了这个窗口中的一些数据,然后想用updatedata(false)来更新窗口的内容,结果在debug版本下面就出现了assert报错,说出错地方是wincore.cpp的888行和889行,就是这两句
  assert((p = pmap->lookuppermanent(m_hwnd)) != null ||
   (p = pmap->lookuptemporary(m_hwnd)) != null);
  assert((cwnd*)p == this);   // must be us
    我用mfc也没有多久,也不太熟悉,翻了翻资料,在http://support.microsoft.com/default.aspx?scid=kb;en-us;147578找到一篇文章,就是说mfc窗口跨线程的问题的,大概意思就是mfc的窗口是线程相关的,每个窗口的handlemap是储存在线程相关的堆栈里面的(thread-local-storage (tls) ),那这样我就理解了为什么上面两句assert会出错了,线程环境都切换了当然线程堆栈的数据也就不一样了.
    这篇文章提供了两种修改方案:
    一种是用fromhandle来获得一个cwnd*,然后再调用updatedata,这个方案我没有实验成功,结果是错虽然不报了,但是界面也没有被更新.
    另外一种是通过发消息的方法转到ui线程去处理.可以在窗口映射一个消息,比如on_message(wm_updatedata, onupdatedata),然后用sendmessage(wm_updatedata, false)传消息给窗口,窗口的消息处理肯定是在ui线程里面,这时候可以用
lresult cprotectpage::onupdatedata(wparam wparam, lparam lparam)
{
 updatedata(wparam);
 return 0;
}
来更新界面,实验是成功的,assert就被消除了.
    还是有点疑惑,就是刚开始直接在工作线程中调用updatedata(false)的时候,虽然有assert报错,但是结果还是正确的,似乎没有什么影响,不知道这个assert到底意味着什么?

本文关键:工作线程中调用UI线程创建的窗口的UpdateData会导致Assert的问题及解决办法.
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top