VB.NET并行与分布式编程(5)-线程状态与调整[2]
Imports System Imports System.Threading Imports System.Diagnostics Imports System.Diagnostics.ThreadState Module Module1 Sub Main() Dim mythread1 As Thread Dim mythread2 As Thread Dim mythread3 As Thread '创建线程对象 mythread1 = New Thread(AddressOf mythreadrun) mythread2 = New Thread(AddressOf mythreadrun) mythread3 = New Thread(AddressOf mythreadrun) Console.WriteLine(Now.ToLongTimeString & "线程对象创建完毕,开始执行线程") '执行线程 mythread1.Start("线程1") mythread2.Start("线程2") mythread3.Start("线程3") '等待线程完成 mythread1.Join() mythread2.Join() mythread3.Join() '线程执行完毕 Console.WriteLine(Now.ToLongTimeString & "线程执行完毕!") End Sub Public Sub mythreadrun(ByVal data As Object) Dim mynum As Integer '分配一个新的槽,这个槽存放线程本地数据,槽名称为 'myjg,名称必须唯一 Dim jg As LocalDataStoreSlot jg = Thread.GetNamedDataSlot("myjg") Thread.SetData(jg, 30) Try For mynum = 1 To 10 Thread.SetData(jg, Thread.GetData(jg) - mynum) Console.WriteLine(Thread.CurrentThread.ManagedThreadId & "==>" & Now.ToLongTimeString & "=>" & (Thread.GetData(jg) + mynum) & "-" & mynum & ",计算结果为:" & Thread.GetData(jg)) '获取线程状态 Thread.Sleep(5) Dim value As ProcessThreadCollection Dim pt As ProcessThread value = Process.GetCurrentProcess().Threads For Each pt In value If pt.ThreadState = Wait Then Console.WriteLine(pt.Id & "=>等待原因:" & pt.WaitReason.ToString) Else Console.WriteLine(pt.Id & "=>线程状态:" & pt.ThreadState.ToString) End If Next Next Catch Console.WriteLine(data & " " & Now.ToLongTimeString & "线程异常终止!") '终止线程 Thread.CurrentThread.Abort() Finally Thread.FreeNamedDataSlot("myjg") End Try End Sub End Module
我们在上面代码中加入了线程状态的输出
Console.WriteLine(pt.Id & "=>线程状态:" & pt.ThreadState.ToString)
在上一节和本节的上面代码中,与线程状态与调度有关的核心代码如下 :
Dim value As ProcessThreadCollection
Dim pt As ProcessThread
value = Process.GetCurrentProcess().Threads
For Each pt In value
If pt.ThreadState = Wait Then
Console.WriteLine(pt.Id & "=>等待原因:" & pt.WaitReason.ToString)
Else
Console.WriteLine(pt.Id & "=>线程状态:" & pt.ThreadState.ToString)
End If
Next
其中
1)得到当前进程的所有线程集合:
value = Process.GetCurrentProcess().Threads
2)在线程集合中迭代
For Each pt In value
.......
next
3)判断该线程的状态是不是等待
If pt.ThreadState = Wait Then
4)等待原因
Console.WriteLine(pt.Id & "=>等待原因:" & pt.WaitReason.ToString)
注意pt.WaitReason和pt.ThreadState 都是枚举值,因此在前面
Imports System.Diagnostics.ThreadState
5)如果线程没有处于等待状态,则输出线程的当前状态
Console.WriteLine(pt.Id & "=>线程状态:" & pt.ThreadState.ToString)
6)pt.Id为获取线程的唯一标识符,ManagedThreadId 属性的值是一个整数,表示此托管线程的唯一标识符,不会随时间而变化,即使承载公共语言运行时的非托管代码将线程实现为纤程。
2、线程的名字可以使用Thread.Name ,它 是包含线程名称的字符串类型的 属性
我们把上面的代码改一下,加入thread.Name,不再像以前那样通过 mythread1.Start("线程1")
传入一个字符串参数进入线程,让线程内部知道它的名字
Imports System Imports System.Threading Imports System.Diagnostics Imports System.Diagnostics.ThreadState Module Module1 Sub Main() Dim mythread1 As Thread Dim mythread2 As Thread Dim mythread3 As Thread '创建线程对象 mythread1 = New Thread(AddressOf mythreadrun) mythread2 = New Thread(AddressOf mythreadrun) mythread3 = New Thread(AddressOf mythreadrun) mythread1.Name = "thread_1" mythread2.Name = "thread_2" mythread3.Name = "thread_3" Console.WriteLine(Now.ToLongTimeString & "线程对象创建完毕,开始执行线程") '执行线程 mythread1.Start() mythread2.Start() mythread3.Start() '等待线程完成 mythread1.Join() mythread2.Join() mythread3.Join() '线程执行完毕 Console.WriteLine(Now.ToLongTimeString & "线程执行完毕!") End Sub Public Sub mythreadrun() Dim mynum As Integer '分配一个新的槽,这个槽存放线程本地数据,槽名称为 'myjg,名称必须唯一 Dim jg As LocalDataStoreSlot jg = Thread.GetNamedDataSlot("myjg") Thread.SetData(jg, 30) Try For mynum = 1 To 10 Thread.SetData(jg, Thread.GetData(jg) - mynum) Console.WriteLine(Thread.CurrentThread.Name & "==>" & Now.ToLongTimeString & "=>" & (Thread.GetData(jg) + mynum) & "-" & mynum & ",计算结果为:" & Thread.GetData(jg)) Thread.Sleep(5) Next Catch Console.WriteLine(Thread.CurrentThread.Name & " " & Now.ToLongTimeString & "线程异常终止!") '终止线程 Thread.CurrentThread.Abort() Finally Thread.FreeNamedDataSlot("myjg") Console.WriteLine(Thread.CurrentThread.Name & " " & Now.ToLongTimeString & "线程运行完毕!") End Try End Sub End Module
下面我们可以进一步改进,输出进程名称,并将当前进程做为参数传入线程
Imports System Imports System.Threading Imports System.Diagnostics Imports System.Diagnostics.ThreadState Module Module1 Sub Main() Dim mythread1 As Thread Dim mythread2 As Thread Dim mythread3 As Thread '创建线程对象 mythread1 = New Thread(AddressOf mythreadrun) mythread2 = New Thread(AddressOf mythreadrun) mythread3 = New Thread(AddressOf mythreadrun) mythread1.Name = "thread_1" mythread2.Name = "thread_2" mythread3.Name = "thread_3" Console.WriteLine(Now.ToLongTimeString & "线程对象创建完毕,开始执行线程") Dim myprocess As Process = Process.GetCurrentProcess() Console.WriteLine("进程名称:" & myprocess.ProcessName) '执行线程 mythread1.Start(myprocess) mythread2.Start(myprocess) mythread3.Start(myprocess) '等待线程完成 mythread1.Join() mythread2.Join() mythread3.Join() '线程执行完毕 Console.WriteLine(Now.ToLongTimeString & "线程执行完毕!") End Sub Public Sub mythreadrun(ByVal myprocess As Object) Dim mynum As Integer Dim value As ProcessThreadCollection Dim pt As ProcessThread '分配一个新的槽,这个槽存放线程本地数据,槽名称为 'myjg,名称必须唯一 Dim jg As LocalDataStoreSlot jg = Thread.GetNamedDataSlot("myjg") Thread.SetData(jg, 100) Try For mynum = 1 To 10 Thread.SetData(jg, Thread.GetData(jg) - mynum) Console.WriteLine(Thread.CurrentThread.Name & "==>" & Now.ToLongTimeString & "=>" & (Thread.GetData(jg) + mynum) & "-" & mynum & ",计算结果为:" & Thread.GetData(jg)) Thread.Sleep(50) value = myprocess.Threads For Each pt In value If pt.ThreadState = Wait Then Console.WriteLine(pt.Id & "=>等待原因:" & pt.WaitReason.ToString) Else Console.WriteLine(pt.Id & "=>线程状态:" & pt.ThreadState.ToString) End If Next Next Catch Console.WriteLine(Thread.CurrentThread.Name & " " & Now.ToLongTimeString & "线程异常终止!") '终止线程 Thread.CurrentThread.Abort() Finally Thread.FreeNamedDataSlot("myjg") Console.WriteLine(Thread.CurrentThread.Name & " " & Thread.CurrentThread.Priority.ToString) Console.WriteLine(Thread.CurrentThread.Name & " " & Now.ToLongTimeString & "线程运行完毕!") End Try End Sub End Module
注意以上代码的下面几个部分
1)
Public Sub mythreadrun(ByVal myprocess As Object)
2) Dim myprocess As Process = Process.GetCurrentProcess()
Console.WriteLine("进程名称:" & myprocess.ProcessName)
'执行线程
mythread1.Start(myprocess)
mythread2.Start(myprocess)
mythread3.Start(myprocess)