16,555
社区成员
发帖
与我相关
我的任务
分享
Imports System.Threading
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim query = From i In Enumerable.Range(0, 20).AsParallel '注意,关键是 .AsParallel
Select TestCls.TestSub(i)
For Each result In query
Me.ListBox1.Items.Add(result)
Next
End Sub
End Class
Public Class TestCls
Shared rnd As New Random
Public Shared Function TestSub(i As Integer) As String
Thread.Sleep(rnd.Next(2000))
Return i & "__threadId=" & Thread.CurrentThread.ManagedThreadId & ", 返回值=" & 100
End Function
End Class
Imports System.Threading
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim query = From i In Enumerable.Range(0, 20).AsParallel '注意,关键是 .AsParallel
Select TestCls.TestSub(i)
For Each result In query
Me.BeginInvoke(Sub()
Me.ListBox1.Items.Add(result)
End Sub)
Next
End Sub
End Class
Public Class TestCls
Shared rnd As New Random
Public Shared Function TestSub(i As Integer) As String
Thread.Sleep(rnd.Next(2000))
Return i & "__threadId=" & Thread.CurrentThread.ManagedThreadId & ", 返回值=" & 100
End Function
End Class
这就像 #3 楼说的,使用 PLinq 可以轻松地用一个 .AsParallel 搞定多线程,用不着你写复杂的代码。Imports System.Threading
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim lst As New List(Of TestCls)
For i = 0 To 20
Dim obj As New TestCls With {.i = i}
AddHandler obj.GetResult, Sub(n As Integer) '显示结果。它在子线程中运行
Dim 线程id = Thread.CurrentThread.ManagedThreadId
Me.BeginInvoke(Sub()
Me.ListBox1.Items.Add(obj.i & "__threadId=" & 线程id & ", 返回值=" & n)
End Sub)
End Sub
lst.Add(obj)
Next
For Each j In lst
ThreadPool.QueueUserWorkItem(Sub()
j.TestSub()
End Sub)
Next
End Sub
End Class
Public Class TestCls
Public i As Integer
Public Event GetResult(ByVal Num As Integer)
Public Sub ReturnResult(ByVal Num As Integer)
RaiseEvent GetResult(Num)
End Sub
Shared rnd As New Random
Public Sub TestSub()
Thread.Sleep(rnd.Next(2000))
ReturnResult(100)
End Sub
End Class
你可以看到,这里创建了20个 TestCls 对象,分别设置了它们的回调事件处理委托方法。然后在一个 for each 循环中,分别注册给系统线程池,以子线程来调用每一个对象的 TestSub 方法。
在事件抛出时,是先注册的事件处理方法在主线程的窗体子控件打印了:输入值、线程id、返回值。Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Parallel.For(0, 5, Sub(n) MsgBox(String.Format("1 + {0} ={1}", n, Add(1, n))))
End Sub
Private Function Add(ByVal x As Integer, y As Integer) As Integer
Thread.Sleep(y * 1000) '模拟长时间运算
Return x + y
End Function