有一个项目,一旦点下按钮后,用死循环不停的读数据,读出后立刻用可视化的方法显示。
如果不采用多线程的方法,程序运行都正确,但无法关闭窗口,不清楚是窗口无法通过关闭按钮来接受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. Codeforces Gym101606 D.Deranging Hat (2017 United Kingdom and Ireland Programming Contest (UKIEPC 2017))

    D Deranging Hat 这个题简直了,本来想的是冒泡排序然后逆着输出来的,后来发现不对,因为题目上求的是最优解,而且冒泡的话,输出结果有的超出10000行了,所以就是把一开始的,排好序的字母标 ...

  2. RSA 公钥加密算法

    RSA公钥加密算法是1977年由Ron Rivest.Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的. 这个算法的名字也是他们三个人名字首字母,RSA算法基于一个十分简单的数 ...

  3. CDOJ_24 八球胜负

    8球是一种台球竞赛的规则.台面上有7个红球.7个黄球以及一个黑球,当然还有一个白球.对于本题,我们使用如下的简化规则:红.黄两名选手轮 流用白球击打各自颜色的球,如果将该颜色的7个球全部打进,则这名选 ...

  4. [BZOJ5286][洛谷P4425][HNOI2018]转盘(线段树)

    5286: [Hnoi2018]转盘 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 15  Solved: 11[Submit][Status][Di ...

  5. 1007 Maximum Subsequence Sum

    Given a sequence of K integers { N​1​​, N​2​​, ..., N​K​​ }. A continuous subsequence is defined to ...

  6. Css实现一个菜单导航

    提要:使用大div定位设置为relative,子div设置为absolute实现菜单下拉 实现代码: <!DOCTYPE html> <html lang="en" ...

  7. Eclipse 教程

    Eclipse 教程 Eclipse 是一个开放源代码的.基于 Java 的可扩展开发平台. Eclipse 是 Java 的集成开发环境(IDE),当然 Eclipse 也可以作为其他开发语言的集成 ...

  8. Web文件的ContentType类型大全

    ".*"="application/octet-stream"".001"="application/x-001"&qu ...

  9. Linux/ visual studio 编译使用Poco

    1. 下载源码包.在POCO的官方网站下载最新的POCO源码包.http://pocoproject.org/download/index.html2.解压源码包.下载的文件名是“poco-1.6.0 ...

  10. Tessellation (曲面细分) Displacement Mapping (贴图置换)

    DirectX 11 Tessellation (曲面细分)-什么是 Tessellation (曲面细分) ? 它为什么可以起到如此关键的数据? 随着近期人们对 DirectX 11 的议论纷纷,你 ...