如何在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函数,因此会造成循环所在窗体无响应.

而此时主窗体不受影响.

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

完整的代码,在此下载:

下载文件 点击下载此文件

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



下载文件 点击下载此文件


评论: 24 | 引用: 0 | 查看次数: 9271
世纪长工
世纪长工[2011-10-10 12:00 PM | ]
我每次使用FTP传输数据的时候都很慢的。所以想把FTP和信息录入分开。这样就不会因为FTP慢而影响到信息录入了。
回复来自 admin 的评论 admin 于 2011-10-12 02:18 PM 回复
如果是这样的话,可以参考这个代码:
http://blog.m5home.com/article.asp?id=65
将会挂起的操作放在一个类里,并添加一个事件,用于操作完成后触发调用者.
再用CreateObject创建对象,则它就在另一线程中了.
主线程调用后就返回,然后等待操作完成的事件.
世纪长工
世纪长工[2011-09-07 09:43 PM | ]
我想做一个可以一边记录信息,一边将已经记录好的信息用FTP进行传输的程序,请问,你有什么好的办法吗?
回复来自 admin 的评论 admin 于 2011-09-08 05:35 PM 回复
这个功能不需要什么特殊的地方吧.

信息的记录与FTP上传,没有冲突啊!

你可以设置为定时+定量上传,比如30分钟内如果有新内容就上传,以及如果新内容超过500K就上传.
hyzzk
hyzzk[2011-07-02 04:39 PM | ]
如果要是把要执行的代码放到一个自定义控件中,然后用地址函数取得执行状态,在用load 创建控件数组来实现呢,应该是可靠的吧,必竟active可以设置为独立的嘛


回复来自 admin 的评论 admin 于 2011-07-03 03:19 AM 回复
没有明白你的意思.....
ligui
ligui[2010-12-22 09:31 AM | ]
老马,在赞一个啊
yimins
yimins[2010-05-09 10:02 PM | ]
不错不错!下载回去好好研究一下哈~~~
vbnewer
vbnewer[2010-02-06 01:57 PM | ]
如果将主窗体的参数传递给新线程或者使用全局变量,就会导致主窗体卡死,有办法解决吗?
回复来自 admin 的评论 admin 于 2010-02-06 09:23 PM 回复
除非你是调用了另一线程中的过程,而这个过程是耗时的,未处理完前不返回,那样的话肯定会挂起啊.

这种情况比较方便的是使用一个定时器,在调用过程中存储参数,并启动定时器,让过程立即返回.

然后定时器触发后再调用真正的处理过程.......
阿智
阿智[2009-10-23 11:22 AM | ]
感谢您的这篇文章,但是我还是有点问题。我比如想在界面上有个文本框,里面的数字,从1变到1000000
怎么写,才能不影响界面?
多指教!
回复来自 admin 的评论 admin 于 2009-10-23 03:16 PM 回复
如果仅仅是这个功能,那好象没有必要使用多线程吧.
三断笛
三断笛[2009-10-08 08:08 PM | ]
这种方法无法在MDI工程里使用,可惜
回复来自 admin 的评论 admin 于 2009-10-08 08:49 PM 回复
这没办法,MDI窗体好象有个什么数据共享还是什么之类的问题,比较麻烦,所以微软干脆禁止了MDI窗体在多线程工程中的使用.....
cfx
cfx[2009-07-11 06:54 AM | ]
其实本质上来说,单元线程模型是介于多线程和多进程之间的。
之所以采用线程,主要就是为了共享存储空间和减小开销。否则还不如采用多进程。
回复来自 admin 的评论 admin 于 2009-10-08 08:48 PM 回复
大量使用时的开销的确很大,特别是在线程间调度的操作比较多的时候.

我一般是用于UI分离,达到不挂起UI的效果即可......
admin
admin[2009-07-01 12:55 PM | ]
引用来自 ibin 引用来自 ibin
为什么在线程里不能实现winsock.accept
测试了下,建立不了连接

WINSOCK内部貌似是多线程实现的

你只要保证你的数据处理过程不会卡死就不需要多线程处理.

至于这个连接问题,有可能是你代码的问题,我的第二个例子就是使用WINSOCK做下载的示例,没有发现你所说的问题.
ibin
ibin[2009-07-01 12:08 PM | ]
线程里的winsock.accept状态为7.客户端仍处理正在连接状态
ibin
ibin[2009-07-01 12:06 PM | ]
为什么在线程里不能实现winsock.accept
测试了下,建立不了连接
admin
admin[2009-06-10 11:07 PM | ]
引用来自 vansoft 引用来自 vansoft
msgbox会卡死二边
应该做到只卡一面

自己做一个MSGBOX窗体?
编译后应该是只卡当前线程的
vansoft
vansoft[2009-06-09 11:27 AM | ]
msgbox会卡死二边
应该做到只卡一面

自己做一个MSGBOX窗体?
admin
admin[2009-05-26 10:40 PM | ]
关于这份代码多开的解决方案请见: http://www.m5home.com/bbs/dispbbs.asp?boardid=27&Id=2557
admin
admin[2008-11-05 04:20 PM | ]
引用来自 ccccjjjj 引用来自 ccccjjjj
请问我要加载N个线程应该怎么做?

建立多个对象即可

把对象生成一个数组,使用CreateObject来初始化.
ccccjjjj
ccccjjjj[2008-11-05 09:03 AM | ]
请问我要加载N个线程应该怎么做?
admin
admin[2008-07-30 01:30 AM | ]
引用来自 孤帆 引用来自 孤帆
什么破过滤


没办法,机器人太多了.添加了不少广告方面的过滤.

我可不想我的BLOG变成广告页.
孤帆
孤帆[2008-07-30 12:23 AM | ]
什么破过滤
风飞雪
风飞雪[2008-05-04 10:54 AM | ]
不错
确实增加了一个线程
主窗口也不卡
admin
admin[2008-04-21 09:42 PM | ]
卡死了?不可能吧.

别告诉我你没编译?

IDE环境是单线程的哦,别搞错了.
dd
dd[2008-04-21 02:28 PM | ]
你的超大循环把I窗体卡死了,同时也主窗体卡死了。。。。。
admin
admin[2008-03-12 12:39 PM | ]
这个就不清楚了...一直在VB6里编程,多线程一点都不熟

多线程有些什么调试手段,也不知道...
兔子
兔子[2008-03-11 01:39 PM | ]
你的demo像是不好调试的.