一、VB6天生就支持vb6多线程程的论证、证据和历史:
网上一直有流传了将近十年的谣言说VB6天生就不支持vb6多线程程。很久以前我也信以为真了直到发现了老马写的ACTIVEXEXEvb6多线程程礻例(示例压缩包中已附带)。稍作研究后发现这是微软官方本来就有提供的vb6多线程程方案只不过这种标准方法使用起来很麻烦,参考資料十分稀少造成了多年以来无人问津甚至有人听都没听说过。所以正确的说法应该是“VB6vb6多线程程实现起来有点麻烦”或者“支持的不呔好”说“天生就不支持”显然过分至极。就像VB6的类没有C++和JAVA的灵活并且一个自定义类就要用一个文件,类多了加载文件都得卡一会這时,只能说“VB6对类的支持不太好用起来有点麻烦”,如果有人说“VB6天生就不支持类”那就闹笑话了用起来有点麻烦不等于没有。
进┅步研究后发现我们,哪怕是刚入门的菜鸟们都在无意之中用VB6写出了vb6多线程程程序。比如你在窗口加个WMP(windows media
player)控件做播放器编译为EXE后,你會发现任务管理器里面你的程序的线程数绝对不是1了。VB6写出的程序是标准的WIN32程序放到WIN10下面,系统都不敢说“这不是有效的WIN32程序”而使其良好运行。能够拥有多个线程是所有WIN32程序的“天赋”
真正对VB6有限制的是它必须依赖VB6运行库,就像.net程序必须要netframework一样(由于VB6历史悠久所有的非极端阉割版系统都自带VB6运行库,而.net就不一定了)用API的方式创建的子线程由于没有初始化运行库,编译出来的程序除了加减乘除什么也不能做。于是有段时间很流行PCODE大法似乎这种方式能让子线程和主线程共享部分运行库。但是不能解决根本问题并且执行效率拙計!
直到前几年VBGOOD论坛的老汉(ID:download)发现了微软未公开的初始化运行库的函数,以及诱导相关组件完全初始化的方法能编译为本机代码稳定运荇的VB6vb6多线程程技术成为了可能。本套技术示例就用到了这些函数
由于是纯API进行线程操作,IDE并不知道我们使用了vb6多线程程所以多数情况丅需要编译为EXE运行后才有完整的稳定性和真实的效果(其实GDI+和子类化又何尝不是如此,调试时稍不注意就闪退!)这会带来调试上的些許麻烦,关于这方面的调试技巧在第6个示例中有说明。
本套VB6vb6多线程程方法有如下特点:
1、稳定:采用的是微软官方藏起来未公开的对VB6 ACTIVEXEXEvb6多線程程环境进行初始化的一套流程。
区别是这套流程在API新建的子线程中运行了而不是在操作麻烦的ACTIVEXEXE中。
此外没有使用内嵌汇编,外部調用自制DLL等方法是“纯天然”的VB6vb6多线程程。
2、高效:可以编译为本机代码运行而不是龟速PCODE。优化选项可以随意勾选保证了执行效率。
3、方便快捷:限制较少所有的工作都可以在一个工程内全部完成。对API的声明既可以用TLB也可以用VB6最传统的Declare XXX
生成的EXE在自带有VB6运行库的任哬WINDOWS系统上都可运行,就vb6多线程程技术本身而言无需额外注册其它组件且生成的程序可以被加壳。
4、参考资料易得:由于是系统API创建的vb6多線程程绝大部分的技术原理和C系列语言的vb6多线程程是相通的。完全可以参考C的相关技术和代码
这对以后想学C系列语言的爱好者们来说昰个很好的适应性“热身运动”。
5、实用学习成本低:这是以上四个特点的综合。有一定编程功力的爱好者能很快上手学习成本远低於另外再学一门语言,
而且很多内容都是所有的vb6多线程程技术本来就都要学习的并且该套方法继承了VB6快速开发的初衷和特点,具有很强嘚实用性
使用VB6vb6多线程程的必备知识储备:
1、熟练VB6的基本语法
2、能熟练的使用API
5、最好能懂一点点指针和各种数据在内存中的存在方式
6、大致了解线程与进程的关系和区别,了解vb6多线程程的特点和意义(这些纯理论的知识在百度上很容易找到主要是上面几点需要时间掌握。)
使用VB6vb6多线程程保证其稳定性的注意事项:
1、VB6vb6多线程程程序在IDE下的稳定性和子类化相当,编译为EXE后才具有完整的稳定性
2、VB6vb6多线程程程序必须以SUB MAIN作为启动对象(在在工程——属性——启动对象中自行设置)
3、由于是用的是ACTIVEXEXE的初始化流程(但是工程类型必须选择标准EXE!)所以必須在SUBMAIN中处理重入问题(模版中已经写好了)
4、VB6主线程(就传统的拖控件,在事件里面写代码的那个线程)不要先于子线程退出否则容易發生难以预料的情况
5、不要在子线程中直接定义定长数组(例如dim arr(100) as long),否则将导致程序崩溃
在子线程调用的子过程?子函数?对象?类中定义定長数组不会有任何问题?
直接使用之前在标准模块(BAS)中定义好的公有定长数组也没问题。
6、多个线程在程序逻辑上有可能会同时操作同一塊内存时(新手可以理解为同时操作同一变量或HDC之类的东东时)要特别注意加锁。(原子操作不必加锁详情请百度)
即使用临界区排隊处理,否则易导致数据混乱甚至程序崩溃但是DOEVENTS不能进入临界区,否则易造成相关的线程锁死
再次感谢为VB6vb6多线程程技术做出贡献的老馬、老汉、IZERO、TGY等等前辈们
特别是老汉(VBGOOD论坛的Download),没有他发现的微软藏起来的函数方便、快速的VB6vb6多线程程技术就没法实现!
|