有一个项目,一旦点下按钮后,用死循环不停的读数据,读出后立刻用可视化的方法显示。
如果不采用多线程的方法,程序运行都正确,但无法关闭窗口,不清楚是窗口无法通过关闭按钮来接受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. configure.ac:3: error: Autoconf version 2.68 or higher is required

    configure.ac:3: error: Autoconf version 2.68 or higher is required 参考博客:https://blog.csdn.net/pretty ...

  2. LeetCode OJ——Subsets

    http://oj.leetcode.com/problems/subsets/ 计算一个集合的子集,使用vector<vector<int> >,使用了进制的思想. #inc ...

  3. sudo apt-get upgrade 不成功遇到问题

    一. sudo apt-get update 和 sudo apt-get upgrade 出错:(Ubuntu更新过程被中断后的问题) Ubuntu的更新过程是先下载完源里的文件就开始执行升级,如果 ...

  4. java excel导出(基于注解)

    小白,做日志只是为了方便自己查看,能帮到别人当然更好,不喜勿喷. 上代码 依赖: <dependency> <groupId>org.apache.poi</groupI ...

  5. TF-IDF学习笔记

    计算文本的权重向量,有个很有效的权重方案:TF-IDF权重策略.TF-IDF含义是词频逆文档频率,指的是,如果某个词或短语在一篇文章中出现的频率高,并且在其他文章中很少出现,则认为此词或短语具有很好的 ...

  6. GitBook一个专注于帮助文档的工具

    官网:https://www.gitbook.com GitHub组织:https://github.com/gitbookio GitBook一个专注于帮助文档的工具,比如: 1.简单的左侧列表右侧 ...

  7. erlang debugger

    http://erlang.org/doc/apps/debugger/debugger_chapter.html

  8. springboot多环境配置

    springboot多环境(dev.test.prod)配置 2017-07-17 10:33 1290人阅读 评论(0) 收藏 举报  分类: spring boot(6)  版权声明:本文为博主原 ...

  9. ios高效开发--blocks相关

    1.替换delegate       如果我们有2个viewController,a和b,当我们从a界面push到b后,在b上面触发了一些事件,这些时间又会影响到a界面上的内容.            ...

  10. 数组对象(NSArray和NSMutableArrray)

    Objective-C中除了可以使用C中的基本数组外,如int[5],char word[] ={‘a’,'b’,'c’};Foundation还提供了NSArray类.Foundation是有序的对 ...