扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
这个没法做到。原因
我们提供的服务有:成都网站设计、成都网站制作、微信公众号开发、网站优化、网站认证、吕梁ssl等。为上1000+企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的吕梁网站制作公司
1)当你将方法排入线程池队列后,此方法在有线程池线程变得可用时执行。
2)线程池中某个线程的可用与不可用,是由.net 后台决定,用户程序无法控制的
3)正如你观察到的:线程启动的时间不同,有快有慢,这恰恰说明线程池起作用了:线程池的调度试图让程序响应达到最佳。
Sub Main() Dim thr As New Thread(AddressOf 循环) thr.Start("a") End Sub Sub 循环(a() As String) '这里随你干什么循环也行 For Each i As String In a MsgBox(i) Next End Sub
多线程一般是不推荐用的,因为线程之间如果有共享资源的话会引起竞争,需要加锁处理;而且线程间没有时序关系,所以你在调试中可能会出现异步处理结束顺序与开始处理顺序不一致的情况(我在调试中已经发现该问题)。
针对你提出的这个问题,采用了多线程处理,利用的是BackgroundWorker也就是异步处理控件进行了处理。
代码已经经过调试通过。欢迎交流,如有问题,留下QQ或其他联系方式。
代码如下,并附程序截图。
‘---------------------------------------------------
Imports System.ComponentModel '导入异步控件命名空间
Public Class Form1
Private howmany As Integer = 10
Private AnalysisNumber(0 To howmany - 1) As BackgroundWorker
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ListBox1.Items.Clear()
creatNewBackgroundWorker()
addHandle()
startWork()
End Sub
Private Sub creatNewBackgroundWorker()
For i As Integer = 0 To AnalysisNumber.Length - 1
AnalysisNumber(i) = New BackgroundWorker
Next
End Sub
Private Sub addHandle()
For i As Integer = 0 To AnalysisNumber.Length - 1
AddHandler AnalysisNumber(i).DoWork, AddressOf AnalysisNumber_DoWork
AddHandler AnalysisNumber(i).RunWorkerCompleted, AddressOf AnalysisNumber_RunWorkerCompleted
Next
End Sub
Private Sub startWork()
For i As Integer = 0 To 9
Dim temp(0 To 9) As Integer
For j As Integer = 1 To 10
temp(j - 1) = 10 * i + j
Next
AnalysisNumber(i).RunWorkerAsync(temp)
Next
End Sub
Private Sub AnalysisNumber_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs)
Dim data As Integer()
data = CType(e.Argument, Integer())
Dim temp As Integer
For i As Integer = 0 To data.Length - 1
temp = data(i)
data(i) = temp * temp
Next
e.Result = data
End Sub
Private Sub AnalysisNumber_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs)
Dim data As Integer()
data = CType(e.Result, Integer())
For i As Integer = 0 To data.Length - 1
ListBox1.Items.Add(data(i))
Next
End Sub
End Class
vb6可以实现多线程,不过比较麻烦,vb.net完全支持多线程,请参见msdn.
至于vb6实现多线程请看CreateThread这个API函数.以下有详细方案:
用VB写多线程程序用到的第一个API函数是CreateThread,这个函数的声明如下:
Private 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 Long
这个函数的返回值是线程的句柄,它的参数含义如下:
1.lpThreadAttributes:这个参数表明函数的返回句柄是否可被子进程继承,如果可被继承,则指向一个SECURITY_ATTRIBUTES的结构,否则设为vbnull。
2.dwStackSize:这个参数设置线程的堆栈大小。
3.lpStartAddress:这个参数指明这个线程函数的起始地址。
4.lpParameter:这个参数是传给线程函数的参数。
5.dwCreationFlags:这个参数设置当线程创建时的初始状态,挂起,运行等等。
6.lpThreadId:这个参数是待创建线程的ID号。
假设创建一个管理线程的类clsThreads,用类的一个公用函数Initialize来初始化线程,用ResumeThread和SuspendThread函数来激活线程,实现代码如下:
Private Type udtThread
Handle As Long
Enabled As Boolean
End Type
Private uThread As udtThread
Private Const CREATE_SUSPENDED As Long = H4
Private 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 Long
Private Declare Function ResumeThread Lib "kernel32" (ByVal hThread As Long) As Long
Private Declare Function SuspendThread Lib "kernel32" (ByVal hThread As Long) As Long
Private Declare Function TerminateThread Lib "kernel32" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
Public Sub Initialize(ByVal lpfnBasFunc As Long) '初始化线程
Dim lStackSize As Long, lCreationFlags As Long, lpThreadId As Long, lNull As Long
On Error Resume Next
lNull = 0 '创建一个空指针
lStackSize = 0 '0表示用exe的stack size
lCreationFlags = CREATE_SUSPENDED '表示初始化后先不激活,让别人来激活
uThread.Handle = CreateThread(lNull, lStackSize, lpfnBasFunc, lNull, lCreationFlags, lpThreadId)
If uThread.Handle = lNull Then MsgBox "Create thread failed!"
End Sub
Public Property Get Enabled() As Boolean
On Error Resume Next
Enabled = uThread.Enabled
End Property
Public Property Let Enabled(ByVal vNewValue As Boolean)
On Error Resume Next
If vNewValue And (Not uThread.Enabled) Then
ResumeThread uThread.Handle '激活线程
uThread.Enabled = True
ElseIf uThread.Enabled Then
SuspendThread uThread.Handle
uThread.Enabled = False
End If
End Property
Private Sub Class_Terminate() '终止线程
On Error Resume Next
Call TerminateThread(uThread.Handle, 0)
End Sub
以上内容在类模块clsThreads中,有了它就可以在窗体中实现多线程了。下面以一个简单的例子来说明如何创建多线程(以2个线程为例)。
在form1中添加picture1和picture2两个图片框,以及一个command1按钮,在工程中添加一个bas模块,该模块的代码如下:
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
Public Sub FlickerTop()
Static BgColor As Long
Dim lTick As Long, lCounter As Long
On Error Resume Next
For lCounter = 0 To 60000
BgColor = lCounter Mod 256
Form1.Picture1.BackColor = RGB(BgColor, 0, 0) '变化图片框的颜色
lTick = GetTickCount
While GetTickCount - lTick 10 '延迟10个毫秒时间
Wend
Next
End Sub
Public Sub FlickerBottom()
Static BgColor As Long
Dim lTick As Long, lCounter As Long
On Error Resume Next
For lCounter = 0 To 60000
BgColor = lCounter Mod 256
Form1.Picture2.BackColor = RGB(0, BgColor, 0)
lTick = GetTickCount
While GetTickCount - lTick 10
Wend
Next
End Sub
最后在form1中用下面的代码来创建两个线程,
Option Explicit
Public myThreadTop As New clsThreads, myThreadBottom As New clsThreads
Private Sub Command1_Click()
On Error Resume Next
With myThreadTop
.Initialize AddressOf FlickerTop
.Enabled = True
End With
With myThreadBottom
.Initialize AddressOf FlickerBottom
.Enabled = True
End With
MsgBox "看看会有什么..."
Set myThreadTop = Nothing
Set myThreadBottom = Nothing
End Sub
Sub Main()
Dim thr As Thread
For Pi As Integer=0 To 4 //启用5线程
MulParams =Pi vbTab sFile vbTab dFile vbTab 1 vbTab DelN vbTab cr vbTab cg vbTab cb vbTab IndexI
GlobalParamas(pi)=MulParams .Split(vbTab)
thr=New Thread(AddressOf MyMulThreadCaller)
thr.Start() //启动多线程进程
Application.DoEvents
Next
End Sub
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流