问题:寻求VB中使用多线程的完美解决方案

freelysay 2003-09-30 07:38:24
众所周知,VB6中的In-Process组件不支持多线程。

而采用exe形式的组件有如下缺点:
1. 其方法调用开销实太大据说是直接调用的1000倍以上;
2. 发布的时候需要多带一个exe,实在不爽;
3. 用Timer启动这个线程受限制比较多,而且的确丑陋;

可能的方案:
1. VB调用API实现;
2. 用VC或Delphi之类的工具编写多线程组件,在VB中调用;
3. 在VB内解决,似乎有VB内加汇编的技术,这样编译出来是一个单一的VB exe或dll

问题所在:
在以上可能方案中,
1是否可行;
采用2的话,这个组件要如何编写才能在VB中正常的调用;
能否有谁介绍一下3中的技术原理和实现;
是否有其它更好或更容易的方案。

...全文
248 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
freelysay 2003-11-12
  • 打赏
  • 举报
回复
我也用Delphi试过了,不过还有一个问题,如何在Delphi编写的组件线程当中fire一个事件,在VB中接受这个事件,而这个事件是在VB程序的主线程中接受,可以做到么?
FIFO2003 2003-11-11
  • 打赏
  • 举报
回复
2,用dephi编写多县城的dll,可以。我试过了!
freelysay 2003-10-21
  • 打赏
  • 举报
回复
完整代码在一个叫FreeThreader的组件里面,各位到用Google自己去搜吧。

其实这个问题的实质是撰写MTA的COM组件。
freelysay 2003-10-21
  • 打赏
  • 举报
回复
我说的3是可以实现的(并不是我实现了,而是我看到了实现代码)。这段代码用C写完全可以达到同样的效果,作者用汇编可能原因有二:
1. 对汇编更熟悉;
2. 可以得到最小的动态库(这段代码编译出来是个3584字节的动态库)。

其汇编代码如下:

listing 1: multithread.inc
include \masm32\include\windows.inc
include \masm32\include\gdi32.inc
include \masm32\include\user32.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
include \masm32\include\ole32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\ole32.lib

listing 2: multithread.def
LIBRARY MultiT
EXPORTS
CreateMT
EnableEvents

listing 3: multithread.asm
@echo off
\masm32\bin\ml /c /coff /Cp MULTITHREAD.asm
\masm32\bin\link /DLL /DEF:MULTITHREAD.def /SUBSYSTEM:WINDOWS /LIBPATH:\masm32\lib MULTITHREAD.obj
pause

listing 4: multithread.asm
.586 ; force 32 bit code
.model flat, stdcall ; memory model & calling convention
option casemap :none ; case sensitive

include MULTITHREAD.INC

ExitProc PROTO
EnterProc PROTO :DWORD

.data



Ct dd 0
Guids dd 0,0,0,0

MSVB db "msvbvm60.dll",0
LDLIB db "EbLoadRunTime",0
CCLIB db "EbCreateContext",0
SCLIB db "EbSetContextWorkerThread",0
LDPROC dd 0,0,0

.code





;Param1=AddressToCall,Param2=StackSize,Param3=
CreateMT proc Param1:DWORD,Param2:DWORD,Param3:DWORD,Param4:DWORD,Param5:DWORD,Param6:DWORD,Param7:DWORD

assume FS: nothing

sub esp,4
push esi
push edi
push ecx
mov eax,DWORD PTR fs:[018h]
add eax,0e14h
mov Ct,eax
lea esi,[ebp+014h]
mov edi,OFFSET Guids
cld
mov ecx,4
rep movsd

invoke CreateEvent,NULL,0,0,Param6
mov DWORD PTR [ebp-4],eax
invoke CreateThread,0,Param2,EnterProc,Param1,0,Param3
push eax
invoke WaitForSingleObject,DWORD PTR [ebp-4],0FFFFFFFFh
invoke CloseHandle,DWORD PTR [EBP-4]
pop eax
pop ecx
pop edi
pop esi
ret

CreateMT endp


EnterProc proc Param1:DWORD
assume FS: nothing

sub esp,4

push Guids+0ch
push FS:[0]
mov FS:[0],esp


mov edi,DWORD PTR fs:[018h]
add edi,0e14h
mov esi,Ct
cld
mov ecx,1
rep movsd


invoke CoInitialize,0
invoke OleInitialize,0

lea eax,[ebp-4]
;push eax
invoke CoCreateInstance,Guids,0,017h,Guids+4,eax


invoke OpenEvent,01f0003h,0,Guids+8
invoke SetEvent,eax

call Param1


invoke CoUninitialize
invoke OleUninitialize
invoke ExitThread,0



ret

EnterProc endp

EnableEvents proc

invoke TlsGetValue,3
mov eax,DWORD PTR [eax+028h] ;GET CX
lea ebx,[eax+04ch]

push DWORD PTR [ebx]
push ebx
call LDPROC+4 ;EbCreateContext
call LDPROC+8 ;EbSetContextWorkerThread


;INIT RUNTIME!
mov eax,040003ch
mov eax,DWORD PTR [eax]
lea eax,[eax+0400000h]
mov eax,DWORD PTR [eax+028h]
lea eax,[eax+0400001h]
mov eax,DWORD PTR [eax]
add eax,030h
push DWORD PTR[eax]
push 0400000h
call LDPROC

ret
EnableEvents endp




DllEntry proc hInstance:DWORD, reason:DWORD, reserved1:DWORD
sub esp,4
invoke GetModuleHandle,addr MSVB
mov DWORD PTR [ebp-4],eax
invoke GetProcAddress,eax,addr LDLIB
mov LDPROC,eax
invoke GetProcAddress,DWORD PTR [ebp-4],addr CCLIB
mov LDPROC+4,eax
invoke GetProcAddress,DWORD PTR [ebp-4],addr SCLIB
mov LDPROC+8,eax
mov eax,1
ret
DllEntry Endp

end DllEntry

efei4000 2003-10-09
  • 打赏
  • 举报
回复
我试了,用vb是不可以的!!!
用dll只能在dll里面开一个线程,我尽管在里面开了两个线程,但是它只能运行一个(我先后调用这两个),而且是它运行我放在前面的那个线程!!
其实我在调用它们的时候,vb发现了错误,错误为“dll调用不符合规则”!但是我将它跳过去了。在下面的运行中我于是发现,其实第一个现成它还是启动了,但是第二个线程没有启动!为了验证是否真的运行了放在首位置的现成,我将两个线程交换了一下位置,发现确实只调用了放在首位置的线程,尽管vb报错!!!!
源代码,我下次贴出来!!!
用vb编写多线程看来是一个梦了,呵呵——————————
fbmsf 2003-10-08
  • 打赏
  • 举报
回复
3也是不行的,我用asm写了一个dll,在dll里面开线程,不行。
VB6永远都不会有完美的解决方案
efei4000 2003-10-08
  • 打赏
  • 举报
回复
2呢?在vc的dll中开一个多线程,用vb调用呢?我下去试试!!
wwwdfq1977 2003-09-30
  • 打赏
  • 举报
回复
1和3都不行,因为vb中的所有函数都是为单线程设计的(即使是c库函数也有单线程版和多线程版之分,如果使用单线程版就和vb一样了,不过在单线程环境下效率高),多线程环境下都是不安全的,除非你不使用vb中的函数,这样就失去了意义
另一个方面:vb中多线程程序不可调试,一旦有错vb就崩溃了,你想保存都来不及了
第二种方案的话,你的线程函数也必须是vc或者delphi的不能是vb的,理由同上,不知道这样调用对你的程序有没有意义
比较完美的方案是用vb.net,可惜在win9x环境下不能用
wushuo 2003-09-30
  • 打赏
  • 举报
回复
用vb.net不就可以了,.net支持多线成啊,用thread
rainstormmaster 2003-09-30
  • 打赏
  • 举报
回复
VB 5虽然可以进行多线程编程,但的确不太稳定,特别是调试的时候,很容易崩溃。我还没有发现VB 6在这方面有什么特别好的地方,但进行多线程编程应该使用尽可能新的版本,比如至少应该使用VB6 SP5,因为每个版本都在这方面有些小的进步。有这样的控件来简化多线程编程,Thread Factory for VB6(http://www.halfx.com/Products.htm#ThreadFactory)。

但是,不管怎样实现多线程,安全、稳定都是VB永远的痛。个人意见:用VB6永远都不会有完美的解决方案


关于多线程的实现,可以参考:
http://www.csdn.net/develop/article/18/18660.shtm


jlum99 2003-09-30
  • 打赏
  • 举报
回复
用com组件.
sworddx 2003-09-30
  • 打赏
  • 举报
回复
用VB6永远都不会有完善的解决方案!除非你用刀子逼着微软的开发人员重写一个解释器和编译器(你让BORLAND的人写我更赞成:))

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧