窗体和线程漫谈之工作线程怎样将数据的处理结果显示到窗体

前言

原本这篇博客的标题叫《窗体和线程漫谈》,但想来想去确实不太合适。由于我确实没有写关于窗体和线程的不论什么理论知识,而仅仅是探讨了工作线程怎样将数据的处理结果显示到窗体这个问题,因此又一次改动标题。

另外,关于窗体和线程的相关理论知识。感觉一两句话确实说不清楚,并且《Windows 核心编程》这本书上介绍的也挺好的。有机会再写吧。特别是感觉如今好多人都直接在学 MFC,用 MFC。甚至连窗体过程,消息循环都不太明确,假设能有这样一篇博客也是非常有价值的。

为什么要讨论这个问题

讨论这个依旧是跟之前的项目经历有关。

这里暂且称该项目为 A 项目。

A 项目包含一个client和服务端,client有一个核心的网络模块。该网络模块基于完毕port开发,有多个工作线程。网络模块负责接收来自服务端的数据,对这些数据进行处理,并将终于的处理结果显示在窗体上。那么问题来了,工作线程怎样将数据的终于处理结果显示在窗体上?能够说这个问题不仅仅是 A 项目中遇到的问题。绝大多数网络应用程序都会遇到这个问题。当时 A 项目中採用的方案是在工作线程中利用窗体句柄直接调用对应函数(如 SendMessage)对窗体进行操作。

尽管这样的做法当时并没有出现故障?但它真的没问题吗?假设有问题,我们该採用什么方式将终于的处理结果显示在窗体上呢?

窗体和线程的关系

理论知识是我们回答上述问题的基础。

这方面我找到的唯一资料就是 《Windows 核心编程》 第 26 章 窗体消息。

对这块不太明确的兄弟。能够先看下。这里我们就不详述了。

在工作线程中利用窗体句柄直接调用对应函数对窗体进行操作这样的做法有没有问题

绝大多数情况下。确实不会出现故障。但仅仅是绝大多数情况下。以下是出现故障的两种情况。

  1. 这样的情况是我在项目 A 中亲身经历的。

    当时我在工作线程中调用了 SetFocus 这个函数,结果这个函数并没有成功返回,为什么?以下是 SetFocus 文档中的描写叙述。

    Sets the keyboard focus to the specified window. The window must be attached to the calling thread’s message queue.

    原因非常明显。传递给 SetFocus 函数的窗体句柄代表的窗体必须是属于调用 SetFocus 函数的这个线程的。但工作线程并没拥有该窗体,也没有拥有不论什么窗体。那为什么调用 SetFoucs 函数要有这个需求呢?这个仅仅能说我也不太清楚,但结合 《Windows 核心编程》 第 26 章 中的相关描写叙述。每个线程都拥有自己的键盘焦点,应该在一定程度上回答了这个问题。

  2. 这样的情况是《多线程编程中的主界面安全处理》这篇文章中提到的,大致情况就是拥有窗体的线程正在等待工作线程退出。而工作线程正堵塞于对窗体的 SendMessage 调用中。应该说,这样的情况不是没有可能发生。

说了这么多,说究竟我是不建议在工作线程中利用窗体句柄直接调用相关函数对窗体进程操作这样的做法的,尽管这样的做法绝大多数情况下不会出错,但一旦出现故障,排查起来就比較困难。但我也不全然否认这样的做法,前提是,程序猿自身一定要对程序本身的逻辑认识清楚,比方在工作线程中会不会调用相似 SetFocus 的这类函数,会不会出现上面提到的另外一种情况。

工作线程怎样将终于的处理结果显示到窗体

既然,在工作线程中通过窗体句柄直接调用相关函数对窗体进行操作的这样的做法不太好,那採用什么方法将终于的处理结果显示到窗体上呢?我的方法是调用 PostMessage,通过自己定义消息将数据交给窗体的窗体过程处理。也就是拥有窗体的线程处理。这样的情况下工作线程中唯一和窗体相关的操作就是通过窗体句柄调用 PostMessage。眼下,我并想不到这样的做法有什么有问题的地方,假设有人认为有问题,大家能够一起讨论下。

另外,假设有兄弟知道更好的做法,大家也能够讨论下。

感受和思考

在查找线程和窗体的相关资料过程中。发现非常多人都在问关于线程和窗体的一些问题,在讨论关于窗体和线程的一些概念,并且搞出来一些非常玄乎的东西。但事实上搞清楚一些基础知识,自己独立思考一下。这些问题并不难回答。或许 MFC 相对传统的 Win32 API 确实方便些。但窗体过程。消息循环等一些基本概念还是要理解的。

时间: 2024-10-24 19:41:10

窗体和线程漫谈之工作线程怎样将数据的处理结果显示到窗体的相关文章

分布式缓存系统 Memcached 工作线程初始化

Memcached采用典型的Master-Worker模式,其核心思想是:有Master和Worker两类进程(线程)协同工作,Master进程负责接收和分配任务,Worker进程负责处理子任务.当各Worker进程将各个子任务处理完成后,将结果返回给Master进程,由Master进程做归纳和汇总. 工作示意图如下所示: 其中每个工作线程维护一个连接队列,以接收由主线程分配的客户连接:同时每个工作线程维护一个Libevent实例,以处理和主线程间的管道通信以及和客户连接间的socket通信事件

窗口和线程漫谈

为什么要讨论窗口和线程 讨论这个依然是跟之前的项目经历有关.这里暂且称该项目为 A 项目.A 项目包括一个客户端和服务端,客户端有一个核心的网络模块,该网络模块基于完成端口开发,有多个工作线程,网络模块负责接收来自服务端的数据,对这些数据进行处理,并将最终的处理结果显示在窗口上.那么问题来了,工作线程如何将数据的最终处理结果显示在窗口上?可以说这个问题不仅仅是 A 项目中遇到的问题,绝大多数网络应用程序都会遇到这个问题.当时 A 项目中采用的方案是在工作线程中利用窗口句柄直接调用相应函数(如 S

多线程之:模拟实现线程池的工作原理

[一]线程池存在的价值: ==>多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.    ==>假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间. ==>如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能. [二]合理利用线程池能够带来三个好处. * 第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗. * 第二:提高响应速度.

Thrift第六课 连接中断无法正常清理工作线程

1)继承TServerEventHandler类,获取连接用户的基本信息包括IP和端口,从而监控是否保存有没有清除的连接 TServerEventHandler类提供了用户连接和断开的时候,针对套接字的处理方式,其中提供了两个函数 createContext 当一个新的用户连接的时候会被调用 deleteContext 当用户结束请求处理的时候会被调用 详细的流程可以查看TThreadPoolServer::Task,Task作为TThreadPoolServer的内部类,在Task::run函

线程池的工作原理阅读总结

线程池使用了一种池化技术,和很多其他池化技术一样,都是为了更高效的利用资源,例如链接池,内存池等等 线程池一共有五种状态,运行状态,待关闭状态,停止状态,整理状态,终止状态,一个线程池的核心参数有很多,每个参数都有着特殊的作用,各个参数聚合在一起 后将完成整个线程池的完整工作,每一个工作线程中都维持着一个Thread,线程池的重点之一就是控制线程资源合理高效的使用,所以必须控制工作线程的个数,所以要保存当前线程中的工作线程个数. 线程池设计了两个变量来协作,分别是核心线程数和最大线程数,核心线程

使用线程池与专用线程

高效线程使用圣典 严格来讲,线程的系统开销很大.系统必须为线程分配并初始化一个线程内核对象,还必须为每个线程保留1MB的地址空间(按需提交)用于线程的用 户模式堆栈,分配12KB左右的地址空间用于线程的内核模式堆栈.然后,紧接着线程创建后,Windows调用进程中每个DLL都有的一个函数来通知进程 中所有的DLL操作系统创建了一个新的线程.同样,销毁一个线程的开销也不小:进程中的每个DLL都要接收一个关于线程即将"死亡"的通知,而且内核对象 及堆栈还需释放. 如果一台计算机中只有一个C

C#中的线程(二)线程同步

C#中的线程(二)线程同步 Keywords:C# 线程Source:http://www.albahari.com/threading/Author: Joe AlbahariTranslator: Swanky WuPublished: http://www.cnblogs.com/txw1958/Download:http://www.albahari.info/threading/threading.pdf 第二部分:线程同步基础 同步要领 下面的表格列展了.NET对协调或同步线程动作的

C#在工作线程刷新主界面控件状态小结,单例模式、委托

今日项目开发中需要在服务器界面实时显示客户端连接状态,使用C#的反射机制解决了问题.由于项目比较复杂,现结合一个小例子,对使用C#委托反射机制刷新主界面上的控件状态进行简单小结,希望对新手有所帮助. 一.新建一个C# winform工程:Form_MainUI,界面布局如图1. 代码如下: 1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data;

你真的了解:IIS连接数、IIS并发连接数、IIS最大并发工作线程数、应用程序池的队列长度、应用程序池的最大工作进程数 吗?

IIS连接数 一般购买过虚拟主机的朋友都熟悉购买时,会限制IIS连接数,这边先从普通不懂代码用户角度理解IIS连接数 顾名思义即为IIS服务器可以同时容纳客户请求的最高连接数,准确的说应该叫“IIS限制连接数” 这边客户请求的连接内容包括: 1.网站html请求,html中的图片资源,html中的脚本资源,其他需要连接下载的资源等等,任何一个资源的请求即一次连接(虽然有的资源请求连接响应很快) 2.如果网页采用框架(框架内部嵌套网页请求),那么一个框架即一次连接 3.如果网页弹出窗口(窗口内部嵌