采用定时器起线程~~~具体就是做一个单独功能的定时器,定时时间很短(例子里设为1)作用就是调用下线程函数,然后就关闭自己定时器。代码如下
Private Sub Form_Load()
Timer1.Enabled = False
timer1.Interval =1
End Sub
Private Sub Timer1_Timer() '专门开线程的定时器,开了以后马上关闭自己
call newthread
Timer1.Enabled = False
End SubPrivate Sub Command1_Click()
Timer1.Enabled = true '通过打开定时器开线程
end subPrivate Sub newthread() '需要开的线程函数
...
...
end sub
Private Sub Form_Load()
Timer1.Enabled = False
timer1.Interval =1
End Sub
Private Sub Timer1_Timer() '专门开线程的定时器,开了以后马上关闭自己
call newthread
Timer1.Enabled = False
End SubPrivate Sub Command1_Click()
Timer1.Enabled = true '通过打开定时器开线程
end subPrivate Sub newthread() '需要开的线程函数
...
...
end sub
这种方式仍然是单线程,不能实现多线程。 为啥不是多线程呢,我调用完timer1,然后再调用timer1的时候,不管newthread()有没有执行完都会再起一个newthread()实例的。我只是觉得这种方法对于一些简单的应用可能是一个相当直接的解决方案。因为我已经在我的一个代码里通过这个方法实现了多线程,但是我担心可能带来一些问题。麻烦大家拓展下思维,不要根据经验来下结论。
Private Sub Form_Load()
Timer1.Enabled = False
Timer1.Interval = 1
End SubPrivate Sub Timer1_Timer() '专门开线程的定时器,开了以后马上关闭自己
Call newthread(Now)
Timer1.Enabled = False
End SubPrivate Sub Command1_Click()
Timer1.Enabled = True '通过打开定时器开线程
End SubPrivate Sub newthread(ByVal s As String) '需要开的线程函数
Do While True
Debug.Print s
Loop
End Sub
//看来还没有明白多线程的概念,呵呵~~~~~~举个例子给你:)假设有一天你在写代码~~~~然后突然你后背痒痒了~~~~如果此时你停下写代码的工作,转而挠痒痒去,就是等于你直接在按钮里CALL那个newthread()~~在你没挠完痒痒前,你是没办法继续写代码的~~~~因为你只有两只手(newthread返回前,按钮过程不会返回).再假设,这个时候,如果你有一个保姆,你可以告诉她,"帮我挠痒痒,在后背坐标为X,Y的地方~~~"于是你就可以继续做你的工作;但本质上这并不是你自己完成的,而是由保姆(操作系统)来替你完成的.(TIMER本质上是系统的一个回调,你给了一个回调时间)就如你的代码.继续.再再假设,如果你此时多长了两只手,那么你就可以用那两只手挠痒痒,再用剩下的两只手写代码~~~~这样才是真正的多线程.....也许比喻不是很合适,但大概的意思是这样了,看看能否明白吧:)
......
.......
call newthread
call anothersub
要走到call anothersub这步,必须等call newthread,newthread()这个函数走完。
但是使用本帖的机制后,......
.......
Timer1.Enabled = true '通过定时器来起newthread()这个函数实例
call anothersub
走到call anothersub这步就步需要newthread()这个函数走完。是不是类似在主线程之外另外又开了个线程去做newthread(),这样的形式。而且同时能够多次调用newthread(),而不去考虑前一个newthread()是否完成。当然我也隐约觉得在使用定时器的时候,不能做到同一时间片上的开多线程,例如以下语句就可能只起一个newthread()函数实例
Timer1.Enabled = true
Timer1.Enabled = true
而以下语句就能起2个实例
Timer1.Enabled = true
delay(1) '延迟1秒
Timer1.Enabled = true
但是由于我目前的应用之间会有不少时间间隔所以这个问题还不敏感。
Private Sub Timer1_Timer() '专门开线程的定时器,开了以后马上关闭自己
Timer1.Enabled = False
call newthread
End Sub
我要实现的功能是调用完newthread ()后直接不等newthread ()走完就执行下一条语句,原来的代码
......
.......
call newthread
call anothersub
要走到call anothersub这步,必须等call newthread,newthread()这个函数走完。
那么我要实现调用完newthread ()后直接不等newthread ()走完就执行下一条语句本来可以
......
.......
creatthread(newthread ,.....)
call anothersub
通过另外开一个线程来实现,但是vb6对creatthread()的支持不够,编译好执行会出错所以我用本帖的机制实现了这个需求
.......
Timer1.Enabled = true '通过定时器来起newthread()这个函数实例
call anothersub
走到call anothersub这步就不需要newthread()这个函数走完。
这是一个标准的多线程的逻辑,所以我希望开贴讨论的是这么做带来的问题,而不是这么做是不是多线程
TIMER用起来确实可以隔绝其他代码的影响.TIMER在VB6的优先级是其他控件最高的.再加上上时间定时TIMER出现会出现一点偏差,跑不准了,所谓程序员老感觉TIMER耗资源的原因也就在于此.不过1楼的程序写得还是有点牵强.我觉得应该是把工作代码放到TIMER定时区间里干活,这样回避其他单线程代码对TIMER内代码的约束.
......
.......
call newthread
call anothersub
是需要先执行newthread,等newthread完成返回后再执行anothersub你新的代码
.......
Timer1.Enabled = true '通过定时器来起newthread()这个函数实例
call anothersub
是先执行anothersub,等anothersub完成返回后再过1个毫秒的时间再执行newthread。
你认为在设置Timer1.enabled=true以后timer1就开始计时,1毫秒以后自动执行newthread,不用等到newthread返回你可以继续执行anothersub,newthread和anothersub可能会同时都在执行(anothersub执行时间超过1毫秒),但是实际上在执行Timer1.enabled=true以后Timer1并没有开始计时,而是等到Timer1.Enabled=true所在的这个过程或函数里面的所有代码都执行完成以后才会开始计时,再经过1毫秒的时间以后才会执行newthread里的内容。你的新代码和
…………
…………
call anothersub
call newthread
这种发式的区别是浪费了1毫秒的等候时间!(call anothersub后面没有其他代码)
Option ExplicitPrivate Sub Form_Load()
Timer1.Enabled = False
Timer1.Interval = 1
End SubPrivate Sub Timer1_Timer() '专门开线程的定时器,开了以后马上关闭自己
Call newthread
Timer1.Enabled = False
End SubPrivate Sub Command1_Click()
Timer1.Enabled = True '通过打开定时器开线程
Call newthread2
End SubPrivate Sub newthread() '需要开的线程函数
Dim I As Long, J As String For I = 1 To 200000
J = J & "A" '字符串累加,很费时
Next I
MsgBox "OK-1"
End SubPrivate Sub newthread2() '需要开的线程函数
Dim I As Long, J As String For I = 1 To 200000
J = J & "A" '字符串累加,很费时
Next I
MsgBox "OK-2"
End Sub看看你的同时执行的效果如何吧~~~~~
'BY 嗷嗷叫的老马
'源代码需要使用P-CODE编译Option ExplicitPrivate Declare Function CreateThread Lib "kernel32.dll" ( _
ByVal lpThreadAttributes As Long, _
ByVal dwStackSize As Long, _
ByVal lpStartAddress As Long, _
ByVal lpParameter As Long, _
ByVal dwCreationFlags As Long, _
ByRef lpThreadId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" ( _
ByVal hObject As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32.dll" ( _
ByVal hHandle As Long, _
ByVal dwMilliseconds As Long) As Long
Private Declare Function MessageBox Lib "user32.dll" Alias "MessageBoxA" ( _
ByVal hwnd As Long, _
ByVal lpText As String, _
ByVal lpCaption As String, _
ByVal wType As Long) As LongSub Main()
Dim lRet1 As Long, lRet2 As Long, hThread As Long
MessageBox 0, "开始测试过程!", "测试多线程", 0
lRet1 = CreateThread(0, 0, AddressOf MyThread1, 0, 0, ByVal 0) '建立线程
lRet2 = CreateThread(0, 0, AddressOf MyThread2, 0, 0, ByVal 0) '建立线程
WaitForSingleObject lRet1, -1
WaitForSingleObject lRet2, -1
CloseHandle lRet1
CloseHandle lRet2
MessageBox 0, "结束测试过程!", "测试多线程", 0
End SubPublic Function MyThread1() As Long
Dim I As Long, J As String For I = 1 To 200000
J = J & "A" '字符串累加,很费时
Next I
Call MessageBox(0, "OK-1", ".....", 0)
MyThread1 = 1
End FunctionPublic Function MyThread2() As Long
Dim I As Long, J As String For I = 1 To 200000
J = J & "A" '字符串累加,很费时
Next I
Call MessageBox(0, "OK-2", ".....", 0)
MyThread2 = 1
End Function运行,打开任务管理器,看看线程里面是不是多了两个线程.最好编译.IDE里虽然也是P-CODE,但万一要挂了又得重新整代码了.(我是直接在IDE里运行的,没有问题)
的确只要用本地代码编译,在按下线程弹出的MSGBOX时就挂了.所以得用IDE里一样的P-CODE编译.......
Attribute VB_Name = "mdlThreadProc"
Option ExplicitPublic l_Num As Long
Public IsQuit As LongPublic Declare Function CreateThread Lib "kernel32" _
(ByVal lpThreadAttributes As Any, _
ByVal dwStackSize As Long, _
ByVal lpStartAddress As Long, _
lpParameter As Any, _
ByVal dwCreationFlags As Long, _
lpThreadID As Long _
) As LongPublic Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As LongPublic Declare Sub Sleep Lib "kernel32" _
(ByVal dwMilliseconds As Long)Public Declare Function TerminateThread Lib "kernel32" _
(ByVal hThread As Long, _
ByVal dwExitCode As Long _
) As Long
Public Declare Function ResumeThread Lib "kernel32" (ByVal hThread As Long) As Long Public Declare Function InterlockedIncrement Lib "kernel32" (lpAddend As Long) As LongPublic Declare Function InterlockedExchange Lib "kernel32" (Target As Long, ByVal Value As Long) As LongPublic Declare Function WaitForSingleObject Lib "kernel32.dll" _
(ByVal hHandle As Long, _
ByVal dwMilliseconds As Long _
) As Long'线程函数
Public Sub ThreadProc(ByVal lpParam As Long)
'判断是否通知退出
Do While (InterlockedExchange(IsQuit, ByVal 0&) = 0&)
'工作,l_Num自增
Call InterlockedIncrement(l_Num)
'等一秒
Call Sleep(1000&)
Loop
End Sub
frmMain.frm
VERSION 5.00
Begin VB.Form frmMain
Caption = "Form1"
ClientHeight = 3195
ClientLeft = 60
ClientTop = 345
ClientWidth = 4680
LinkTopic = "Form1"
ScaleHeight = 3195
ScaleWidth = 4680
StartUpPosition = 3 'Windows Default
Begin VB.Timer Timer1
Interval = 1000
Left = 1890
Top = 690
End
End
Attribute VB_Name = "frmMain"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit
Dim hThread As Long
Dim ThreadID As Long
Private Sub Form_Load()
hThread = 0&
IsQuit = 0&
'创建线程
hThread = CreateThread(ByVal 0&, ByVal 0&, AddressOf ThreadProc, ByVal 0&, 0, ThreadID)
End SubPrivate Sub Form_Unload(Cancel As Integer)
Dim iRet As Long
If hThread <> 0& Then
'设置退出标志
iRet = InterlockedExchange(IsQuit, ByVal 1&)
'等一下
'Sleep ByVal 100&
iRet = WaitForSingleObject(ByVal hThread, 10&)
'关闭线程句柄
iRet = CloseHandle(ByVal hThread)
hThread = 0&
End If
End SubPrivate Sub Timer1_Timer()
'显示线程执行结果
Caption = InterlockedExchange(l_Num, ByVal l_Num)
End Sub
Test.VBP
Type=Exe
Form=frmMain.frm
Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\WINDOWS\system32\stdole2.tlb#OLE Automation
Module=mdlThreadProc; mdlThreadProc.bas
IconForm="frmMain"
Startup="frmMain"
HelpFile=""
Title="Test"
ExeName32="Test.exe"
Path32=""
Command32=""
Name="Test"
HelpContextID="0"
CompatibleMode="0"
MajorVer=1
MinorVer=0
RevisionVer=0
AutoIncrementVer=0
ServerSupportFiles=0
VersionCompanyName=""
CompilationType=-1
OptimizationType=0
FavorPentiumPro(tm)=0
CodeViewDebugInfo=0
NoAliasing=0
BoundsCheck=0
OverflowCheck=0
FlPointCheck=0
FDIVCheck=0
UnroundedFP=0
StartMode=0
Unattended=0
Retained=0
ThreadPerObject=0
MaxNumberOfThreads=1[MS Transaction Server]
AutoRefresh=1
我就想用msgbox来说事情的,老马描述得不错啊,支持
是不是我把另外要执行的代码写在MyThread1里,然后调用一下它就会单独执行而不影响主程序呢?
传说那个功能叫做异步,而不是多线程
两个功能有时候能同样的效果,如果被调用的代码被投射到系统里面去,则能够形成一个类似
多线程的效果,但他还是单线程,这就相当于多层嵌套循环,加了一个向外跳N层的条件
可以看看这个, pctgl.vbgood.cn 里面,有个我当初研究过的异步