如何在VB6里面实现稳定的多线程----受人启发而写

嗷嗷叫的老马 2008-02-25 12:48:51
微软官方给出的方案在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
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函数,因此会造成循环所在窗体无响应.

而此时主窗体不受影响.

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

完整的代码,在此下载:

http://www.m5home.com/blog/article.asp?id=54

希望能为没落的VB6带来一丝活力:)

PS:可用分只有170了,留20分保底吧:D
...全文
2315 96 打赏 收藏 举报
写回复
96 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
taoguangye 2012-07-01
这种方式,要访问或修改注册表的,且运行一次后,把EXE文件移到另一个文件夹石再运行就会提示找不到文件了。
  • 打赏
  • 举报
回复
gentlebrother 2009-06-04
mark
  • 打赏
  • 举报
回复
slowgrace 2009-04-26
哇 这么强大的帖子
  • 打赏
  • 举报
回复
xuqin3 2009-03-25
很值得看看,想想的。
  • 打赏
  • 举报
回复
[Quote=引用 88 楼 fox1999 的回复:]
Visual Basic 的单元模型线程

我想你是理解错了。Visual Basic 的单元模型线程是指一个 COM 对多个进程同时调用时的处理方法。

“单元线程”或“单线程”。

单元线程是次一次调用对应于一个实例,每个实例在一个线程里。而 单线程 是指最多只有一个实例,而所有的调用都用这个一实例。
[/Quote]

//

想听一下详细的解释.

对于这个"单元线程",我的理解仅停留在这MSDN里文章的说明上,其实并不很明白.

我的认为就是,由于可以每个对象使用一个线程,那么从宏观上来看,的确是"多线程";

至于本质,当然是与CtrateThread建立的线程是不同的,微软在单元里面又营造了一个COM对象的单独环境.

以前也有试过用CreateThread来做多线程,但是想稳定,真的很麻烦~~:(

我的测试中,线程里不能调用VB6内部函数,只能使用语句,因此要实现一些平时用函数就能实现的功能(如DIR),就得调用API;

而调用API,又要考虑线程本地存储问题,于是我把所有要调用的API都用ODL封装为一个类型库,再在工程里引用.

最终这样子是相对比较稳定了;但是一想到这工作量,不得不放弃....
  • 打赏
  • 举报
回复
hei2008s 2008-03-31
老马的帖子啊!该顶!原来老马也这么强啊!
  • 打赏
  • 举报
回复
谢谢楼上的解释!

明白更多了.

现在我就是想利用这个APARTMENT里面的线程,来做一些事.

比如,像我写的那例子里,把别的任务放到APARTMENT里的对象中去处理~~

这算是一种投机行为吧,嘿嘿....
  • 打赏
  • 举报
回复
fox1999 2008-03-31
COM 的線程模型

1。single thread
使用单线程的应用服务器一次只能服务一个客户端的要求。

使用单线程的应用服务器其执行的效率非常的差劲,尤其是当有许多的客户端应用程序需要使用它的服务时。当有多个客户端调用应用服务器中的服务时,每一个客户端都必须等到在它之前的客户都被服务之后,才可以轮到它被应用服务器服务。
使用单线程虽然在执行效率上不好,但是这种应用服务器却是最好编写的,因为应用服务器无需担心同时会有多个线程在应用服务器中执行,而不必保护全局变量或是方法这中的局部变量。但是使用单线程的应用服务器在真正的分布式应用系统中并不适合使用。

2。apartment model线程模式
ms为了配合WIN95/NT这些真正的多任务操作系统而改善的COM线程模式。一个应用服务器可以有许多不同的APARTMENT。在每一个APARTMENT之中可以有许多的COM对象。在任何时间,在每一个APARTMENT之中只能有一个线程在执行。这个意思是说,每一个APARTMENT在同一时间只能服务一个客户端的调用。

如果一个应用服务器只拥有一个APARTMENT,那么它就只能一次服务一个客户端。所以可以说使用单线程的应用服务器是一种特别的APARTMENT模式的应用服务器。那就是应用服务器只拥有一个APARTMENT。所以如果一个应用服务器虽然是使用APARTMENT线程模式,但是如果应用服务器只建立一个APARTMENT线程的话,那么它仍然一次只能服务一个客户端。

由于使用APARTMENT线程的应用服务器可以包含许多的APARTMENT,所以应用服务器在同一时间可以服务许多不同的客户端的调用。应用服务器可以同时建立许多相同的APARTMENT,如此一来它就可以服务许多要求相同服务的客户端。
  • 打赏
  • 举报
回复
fox1999 2008-03-30
Visual Basic 的单元模型线程

我想你是理解错了。Visual Basic 的单元模型线程是指一个 COM 对多个进程同时调用时的处理方法。

“单元线程”或“单线程”。

单元线程是次一次调用对应于一个实例,每个实例在一个线程里。而 单线程 是指最多只有一个实例,而所有的调用都用这个一实例。
  • 打赏
  • 举报
回复
fox1999 2008-03-30
[Quote=引用 85 楼 myjian 的回复:]
引用 83 楼 fox1999 的回复:
我沒看出來多線程在哪裡


请看看十楼的MSDN原文,或在MSDN里搜索"Visual Basic 的单元模型线程"就可以明白了
[/Quote]

那请看一下我在 84 楼做的回复
  • 打赏
  • 举报
回复
[Quote=引用 83 楼 fox1999 的回复:]
我沒看出來多線程在哪裡
[/Quote]

请看看十楼的MSDN原文,或在MSDN里搜索"Visual Basic 的单元模型线程"就可以明白了
  • 打赏
  • 举报
回复
fox1999 2008-03-29
我想到的多線程是可以做的。不過要下點大力氣

用 API CreateThread 來創建線程。線程體用 PostMessage 把需要的消息發到主窗體

主窗體用 SetWindowLong Hook WndProc. 在 WndProc 中處理線程發來的消息。

內存分配要用堆 LocalAlloc LocalFree 之類的。
  • 打赏
  • 举报
回复
fox1999 2008-03-29
我沒看出來多線程在哪裡
  • 打赏
  • 举报
回复
终于回来了~~~~~~~~~~~~
  • 打赏
  • 举报
回复
water32 2008-03-10
多线程用API来实现,一编绎成EXE,运行就死
VB真让失望啊!
  • 打赏
  • 举报
回复
哈哈

在VB版里面可能有得等了....

我现在是88XX的积分,去年就是8XXX,貌似涨得非常慢.

一是结帖的人太少

二是的确有太多的问题答不上来,只得蹭点分~~

可怜得很.=_=
  • 打赏
  • 举报
回复
也差不多应该结了

看来真正在学VB的人不是很多.....
  • 打赏
  • 举报
回复
放着微软推荐的单元模型线程不用,去使用API实现多线程;

使用API实现多线程,又不下点工夫;

然后扔一句:

VB真让失望啊~~

果然强大.
  • 打赏
  • 举报
回复
结贴了,等俺可用分超过1000时,捐给你一些。
  • 打赏
  • 举报
回复
zzyong00 2008-03-08
呵呵,三更半夜,正好用力顶一下...
  • 打赏
  • 举报
回复
加载更多回复(75)
相关推荐
发帖
VB基础类

7617

社区成员

VB 基础类
社区管理员
  • VB基础类社区
加入社区
帖子事件
创建了帖子
2008-02-25 12:48
社区公告
暂无公告