VB多线程的⼏种实现⽅法概述
转⾃
先说多线程:
⽅法 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个消息正在执⾏的时候,另外的消息⼜被执⾏了,也许这样说会觉得有些乱,稍侯解释。这个帖⼦内容要说的内容就完了,下⼀个帖⼦⾥⾯有个我忘了什么时候写的代码,以那个代码为例,介绍应⽤异步。
==========================================================================
微软官⽅给出的⽅案在MSDN⾥⾯有说,就是使⽤ActiveX EXE那种"单元线程模型".
我也曾经试过,的确可以实现"多线程",只是由于要多⼀个EXE,⽐较⿇烦,后来就没有深⼊了.
结果⼀次⽆意中在VBGOOD中看到⼀段代码,才打通了⼀个关节:为什么不直接使⽤ActiveX EXE写程序呢?!
那段代码⾥⾯,是直接使⽤这种⼯程类型,然后在⼯程内使⽤CreateObject来⽣成⼀个新对象,这样的话,新的对象就⼯作于⼀个单元线程内了.其实这个我也知道,可是就没有想到在ActiveX EXE内部使⽤
看来思路真的不如⼈.....还要多多学习,多多积累.
ActiveX EXE⼯程设置为"独⽴启动"后,貌似只能从Sub Main⾥进⾏初始化.
⽽每个对象的建⽴,都会调⽤⼀次这个过程,因此这个过程需要⼀次性运⾏.
但是MSDN⾥说得很清楚,在单元线程模型⾥⾯,全局变量的范围只能是本单元,因此不能使⽤设置
全局变量来完成这个过程的⼀次运⾏逻辑.原代码⾥使⽤了GetProp等⽅式,感觉不是很好,于是作了⼀下改进,使⽤事件对象来完成此⼯作.
vb编程论坛
Sub Main相关代码如下:
程序代码
Private Const MyEvent As String = "m5home"
Dim hEvent As Long
Sub Main()
If GetEventHandle = 0Then'由于每个新对象的建⽴,都要执⾏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. ⽤第三⽅多线程专业控件,
1.

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。