首页 养生问答 疾病百科 养生资讯 女性养生 男性养生
您的当前位置:首页正文

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

2022-08-08 来源:华佗健康网
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等⽅式,感觉不是很好,于是作了⼀下改进,使⽤事件对象来完成此⼯作.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.ShowEnd IfEnd 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.

因篇幅问题不能全部显示,请点此查看更多更全内容