有一个项目,一旦点下按钮后,用死循环不停的读数据,读出后立刻用可视化的方法显示。
如果不采用多线程的方法,程序运行都正确,但无法关闭窗口,不清楚是窗口无法通过关闭按钮来接受Windows消息,还是接受了消息却没有机会处理?(写个了程序用Spy++观察一下,似乎是没有接受到消息。Delphi IDE可以轻易杀死它,大概是从线程角度杀死的,而不是发消息)
解决方案是:采用多线程。开一个线程读数据,这样主线程仍可用来关闭窗口。但这时候却无法正确显示数据了。原因是Delphi的VCL库不是线程同步的。这时候必须要用TThread的Synchronize来把显示数据的函数同步到主窗口去。注意,这时候不能把读数据的函数也同步进去,这样主程序又无法响应关闭按钮了。应该仅仅同步显示数据的那部分代码。

看来这方面大有讲究,先记下来,以后再补充。代码不贴了,有问题在回复里可以讨论。

另一篇多线程与显示数据的文章:
http://www.cnblogs.com/zhangzhifeng/archive/2011/08/23/2150147.html

他的问题:
DWORD WINAPI ThreadProc(
while(!bTerminate)
{
// 从一个链表中读取信息并且插入到CListCtrl中
// CListCtrl的句柄是通过线程参数传递进来的
for(;;)
{
ReadInfoFromList();
InsertToCListCtrl();
}
}
}
InsertItem的反汇编中发现了如下的代码
call dword ptr [__imp__SendMessageA@16 (7C141B54h)]
可见,InsertItem是必须借助消息循环来完成任务的

解决方案:
while(TRUE)
{

DWORD result ;
MSG msg ;

result = MsgWaitForMultipleObjects(1, &readThreadHandle,
FALSE, INFINITE, QS_ALLINPUT);

if (result == (WAIT_OBJECT_0))
{
break;
}
else
{
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
DispatchMessage(&msg);
}
}

点评:他的意思是,子线程读取数据以后,先要在主窗口上显示数据。然而InsertItem执行的时候把消息发到主窗口去了。然而当开始执行子线程的时候,主窗口就已经处于挂起状态了(因为WaitForSingleObject的原因,无法得到这个唯一的Object所有权,所以主窗口挂起),这样陷入了一个死循环。和我上面那个问题略有不同,但本质一样:子线程想要直接在主窗口显示内容,不同步的话就显示不正确(我的第一个问题),结果要么是同步过头倒是无法响应主线程的其它事件(我的第二个问题),要么是明明主线程挂起了还想让它显示东西(他的第一个问题),而且子线程还等着显示完返回(他的第二个问题),典型的死锁,当然不行。但不知道MFC是不是线程同步的类库?他似乎没有碰到我的第一个问题。

后面的吵架也很有意思,摘录如下:
1. 消息循环只负责获取消息队列中的消息,SendMessageA的消息并不进入消息队列。(点评:正确。但主线程挂起了无法响应是个事实。PostMessage发送的消息是队列消息,它会把消息Post到消息队列中(所以需要等待被处理,因为相对时间长,所以微软把它设计成Post消息后直接返回);SendMessage发送的消息是非队列消息,被直接送到窗口过程处理(一般会立刻直接响应,所以微软把它设计成主线程等待它执行完后才返回)。另外有个问题是,这个SendMessage发生的消息,一旦子线程收到后,会抢在它的队列消息里之前处理吗?如果子线程正在处理某一个消息,是不是至少也要等到当前这个消息处理完才可以处理这个Send来的消息?)
2. SendMessageA发送的消息确实不进入消息循环,但是这个过程是在主线程的上下文中完成的,还是在开的线程中完成的? (点评:问题不是很明确,但发消息是任何线程都有的权力,应该是在子线程中完成发消息的过程)
3. SendMessage的目标窗口如果属于另一个线程,则会发生线程上下文切换,等待另一线程处理完成消息。为了防止另一线程当掉,导致SendMessage永远不能返回,我们可以调用SendMessageTimeout函数(点评:前面的问题属于死锁,可以用Timeout的方法来解决响应问题。但是数据没有显示也是不行的啊,所以TimeOut方法不好)

------------------------------------------------------------------

再来一篇:

当年的某段程序执行时间太长(比如永不休止的外部IO操作),占用了大量CPU资源,却从不放手,会导致其它外部事件/消息无法得到响应(跟我的第一个问题类似,但我的解决方案是多线程,Sleep函数不适用于我的问题),从而出现丢包现象。解决方案:适当加上一个Sleep语句,休眠多少时间自己斟酌(通常100ms也够了)。例子在这里:

http://blog.sina.com.cn/s/blog_5425e1570102e803.html

------------------------------------------------------------------

再来一篇:

PostThreadMessage在线程中应用(以多线程网站数据采集为例)
http://www.cnblogs.com/lwm8246/archive/2011/10/06/2199994.html

PostThreadMessage可帮助线程创建消息队列,但不保证创建成功,需要不停的创建才行。
这篇文章还有一个特点是,次要线程也写了一个while语句来接受和处理自己的线程消息队列,很有意思。

Windows消息、绘图与多线程的更多相关文章

  1. 【转】windows消息和消息队列详解

    转载出处:http://blog.csdn.net/bichenggui/article/details/4677494  windows消息和消息队列 与基于MS - DOS的应用程序不同,Wind ...

  2. windows消息机制(MFC)

    消息分类与消息队列 Windows中,消息使用统一的结构体(MSG)来存放信息,其中message表明消息的具体的类型, 而wParam,lParam是其最灵活的两个变量,为不同的消息类型时,存放数据 ...

  3. windows消息和消息队列

    windows消息和消息队列 转自:http://blog.163.com/zhangjie_0303/blog/static/990827062010113062446767/ 与基于MS - DO ...

  4. WINDOWS消息和窗口简介

    一.WINDOWS的消息和窗口简介:1.什么是windows在这里我就不介绍了,但是作为一个程序员我们要知道WINDOWS最重要的一个也是我们程序员常用的一个东西就是消息.窗口是以消息的形式输入的,窗 ...

  5. Windows 消息循环(1) - 概览

    本文从消息循环是如何驱动程序的这个角度,对 Windows 消息循环进行概览性介绍. 使用 EN5 课件获得更好的阅读体验: [希沃白板5]课件分享 : <Windows培训 - 消息循环> ...

  6. [转]windows消息机制(MFC)

    消息分类与消息队列 Windows中,消息使用统一的结构体(MSG)来存放信息,其中message表明消息的具体的类型, 而wParam,lParam是其最灵活的两个变量,为不同的消息类型时,存放数据 ...

  7. [译]理解Windows消息循环

    出处:http://www.cnblogs.com/zxjay/archive/2009/06/27/1512372.html 理解消息循环和整个消息传送机制对Windows编程来说非常重要.如果对消 ...

  8. 理解Windows消息循环机制

    理解消息循环和整个消息传送机制对Windows编程十分重要.如果对消息处理的整个过程不了解,在windows编程中会遇到很多令人困惑的地方. 什么是消息(Message)每个消息是一个整型数值,如果查 ...

  9. Windows消息机制

    Windows的消息系统是由3个部分组成的: · 消息队列.Windows能够为所有的应用程序维护一个消息队列.应用程序必须从消息队列中获取消息,然后分派给某个窗口.· 消息循环.通过这个循环机制应用 ...

随机推荐

  1. HDU 4405: Aeroplane chess

    类型:概率DP 题意:一条直线下飞行棋,色子六个面等概率.同时存在一些飞机航线,到了某个点可以直接飞到后面的另一个点,可以连飞,保证一个点至多一条航线.求到达或者超过终点 所需要 掷色子的期望次数. ...

  2. Gym 101917 E 简单计算几何,I 最大流

    题目链接 https://codeforces.com/gym/101917 E 题意:给定一个多边形(n个点),然后逆时针旋转A度,然后对多边形进行规约,每个点的x规约到[0,w]范围内,y规约到[ ...

  3. 采集网站特殊文件Meta信息

    采集网站特殊文件Meta信息   元(Meta)信息是描述文件的属性的特殊信息,如文件的所有者.联系方式.机构名.邮件地址等信息.而网站中常常会有共享的文档文件,如PDF.Excel.Word.这些文 ...

  4. LightOj 1215 Finding LCM

    Discription LCM is an abbreviation used for Least Common Multiple in Mathematics. We say LCM (a, b, ...

  5. 为什么BT网络中迅雷的速度会这么快,比其它BT软件快

    先看迅雷加速通道的几个概论,参考:http://www.cnblogs.com/EasonJim/p/6608544.html 我个人理解,在传统BT软件中,基于P2P的网络是不具备以上条件去加速的, ...

  6. 如何使用ssh远程编辑定时任务crontab?

    linxu定时任务使用crontab,编辑crontab可以直接编辑:crontab -e:也可以直接读取文件 crontab file.这两种操作都不需要特殊权限sudo.区别在于,crontab ...

  7. How to create a freehand tool

    http://forums.esri.com/Thread.asp?c=159&f=1707&t=283694&mc=1 http://blog.sina.com.cn/s/b ...

  8. OpenGL - Tessellation Shader 【转】

    http://blog.sina.com.cn/s/blog_8c7d49f20102v4qm.html Patch is just an ordered list of vertices (在tes ...

  9. install nfs and share file

    介绍一下NFS的安装,以及共享文件 NFS(Net File System),通过使用NFS,可以像使用本地文件一样访问远程文件. 它主要解决了数据共享的问题,可以备份容灾. 安装配置 1.以linu ...

  10. Spring源代码由浅入深系列三 refresh

    Spring中的refresh是一个相当重要的方法. 它完毕IOC的第一个阶段,将xml中的bean转化为beanDefinition.具体说明如上图所看到的. 在上图中,创建obtainFreshB ...