在工作线程中更新UI保险方法

一直以来,对在工作线程中更新UI这个问题没有一个全面的认识,看到下面的文章,总算解决了心中长久以来的疑惑;豁然开朗。

个人比较喜欢第一种方法。

 

http://www.itepub.net/html/kaifajingcui/C___VC/2006/0515/38137.html

 

    最近写了个代码,在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到底意味着什么?

posted on 2008-09-04 18:14 FongLuo 阅读(1465) 评论(1)  编辑 收藏 引用

评论

# re: 在工作线程中更新UI保险方法 2010-05-04 19:14 nobody

谢谢分享~~学习了,正遇到这个问题呢  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2008年7月>
293012345
6789101112
13141516171819
20212223242526
272829303112
3456789

导航

常用链接

留言簿

随笔分类(11)

随笔档案(79)

文章档案(1)

收藏夹(38)

学习网站

一般网站

最新随笔

搜索

积分与排名

最新评论

阅读排行榜