VB多线程的几种实现方法概述


转自https://www.cnblogs.com/birdwawe/articles/2507771.html

先说多线程:

方法 1 : CreateThread

不用多说,万变不离其宗,这是 Win32 内创建线程的唯一系统方法,以下介绍的多线程创建方式虽然不直

接接触这个 Win32 APi,但系统也是通过他创建的。


方法 2 : TimerSetEvent

这个函数是 Win32 系统的一个高精度计时器函数,通过调用这个函数,系统会创建一个新的线程,让Timer

回调函数中的代码运行在这个新线程中。


方法 3 : SHCreateThread

很多人应该没见过这个函数,这是 shlwapi.dll 的一个导出函数,这个函数看字面也能理解是个创建多线

程的函数,而且。。。 他是基于对象操作的多线程函数,也就是说他能够稳定的运行一些用上面2种方法创

建,但不能稳定运行的代码。至少这个函数在 IDE 的环境下表现的中规中矩! 使用方法可查 API-GUIDE


方法 4 : 想起来了, CreateRemoteThread

创建远程线程,经测试一点也不稳定,根本没法说下去了,还不如直接调用 CreateThread

但,做为一种线程的创建方法,还是希望能够熟悉一下,如果不用VB写代码,要写跨进程线程,这是一个简单易

行的办法,否则只能继续SetWindowHook了,熟悉汇编指令的还可以远程分配内存写硬编码执行


方法 5 : 简单说下 ActiveX 方式的多线程

论坛里面有用这种方法实现的稳定多线程,代码虽好,但我却不会用,在倡导绿色软件的今天,为了一个多线

程,而注册表里面又要多点xx,不好。。而且卸载麻烦。 用 ActiveX 创建线程与其他方式创建的线程最重

要的地方要主义,任何VB函数的调用最好都建立在新线程中新初始化的对象基础上执行,不要跨对象调用,

而 ActiveX 的安全线程本身也正是利用了这点,不知道研究 ActiveX 的老大们有没注意,利用他特性实

现的多线程,是初始化的一个新的线程,而这个线程中初始化的对象则是整个工程。很大的资源浪费,而且有

时候还不好控制,不是你想要的效果。总之一句话,新线程中要自己初始化新的对象而且最好不要用实例继承


方法 6 : 我的想法

记得以前 CSDN 中有人做过一个代码,通过函数地址抓取函数内的机器码,如果能够知道VB何时已将代码进

行了机器码的转换,然后抓取这些代码放到数组中执行,那应该是非常稳定的。这纯属娱乐的想法,虽然能够

实现,但有点过分了,除非是 VB 多线程的狂热者,否则我想不该花太多力气研究这个。


方法 7 : 异步

论坛中很多人问,timer控件的事件中代码是怎么运行的。其实这就是异步,对于单核CPU多线程的执行方式

与异步简直无异。而最重要的是,VB 中用异步实现代码执行是安全的。其实异步从大家开始Win GUI编程时

就开始接触了。例如窗体的消息循环中就经常会以异步的方式执行,1个消息正在执行的时候,另外的消息又

被执行了,也许这样说会觉得有些乱,稍侯解释。这个帖子内容要说的内容就完了,下一个帖子里面有个我

忘了什么时候写的代码,以那个代码为例,介绍应用异步。

==========================================================================

如何在VB6里面实现稳定的多线程

微软官方给出的方案在MSDN里面有说,就是使用ActiveX EXE那种"单元线程模型".

我也曾经试过,的确可以实现"多线程",只是由于要多一个EXE,比较麻烦,后来就没有深入了.

结果一次无意中在VBGOOD中看到一段代码,才打通了一个关节:为什么不直接使用ActiveX EXE写程序呢?!

那段代码里面,是直接使用这种工程类型,然后在工程内使用CreateObject来生成一个新对象,这样的话,新的对象就工作于一个单元线程内了.

其实这个我也知道,可是就没有想到在ActiveX EXE内部使用

看来思路真的不如人.....还要多多学习,多多积累.

ActiveX EXE工程设置为"独立启动"后,貌似只能从Sub Main里进行初始化.

而每个对象的建立,都会调用一次这个过程,因此这个过程需要一次性运行.

但是MSDN里说得很清楚,在单元线程模型里面,全局变量的范围只能是本单元,因此不能使用设置全局变量来完成这个过程的一次运行逻辑.

原代码里使用了GetProp等方式,感觉不是很好,于是作了一下改进,使用事件对象来完成此工作.

Sub Main相关代码如下:

复制内容到剪贴板 程序代码 程序代码
Private Const MyEvent As String = "m5home"
Dim hEvent As Long
Sub Main()
If GetEventHandle = 0 Then '由于每个新对象的建立,都要执行Main()过程,因此使用事件对象来进行判断.
hEvent = CreateEvent(0&, False, False, MyEvent) '在单元线程下,模块里的全局变量已经没有用了.
frmMain.Show
End If
End Sub

Private Function GetEventHandle() As Long
GetEventHandle = OpenEvent(EVENT_ALL_ACCESS, False, MyEvent)
Call CloseHandle(GetEventHandle)
End Function

Public Function Quit()
Call CloseHandle(hEvent)
End Function

由于事件对象是系统范围的,因此可以比较完美的完成这个工作.


同时事件对象在进程消失后,会自动释放,也方便:)

示例代码可以生成一个新的单元线程,并在这个线程里面显示一个窗体,窗体进行一个大循环.

循环内没有放入DoEvents函数,因此会造成循环所在窗体无响应.

而此时主窗体不受影响.

对象间可以通过一般的调用与事件来进行通讯.

完整的代码,在此下载:

下载文件 点击下载此文件

**************************改一下,添加一个简单测试例子***********************

参考:

0. 用第三方多线程专业控件ThreadFactory.exe,

1. VBA实现多线程

 2.http://ishare.iask.sina.com.cn/f/330AA87FEk2.html


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM