900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > VB.NET学习笔记:多线程编程

VB.NET学习笔记:多线程编程

时间:2018-07-22 01:39:44

相关推荐

VB.NET学习笔记:多线程编程

在《多线程加委托实现等待窗体(loading正在加载界面),运行超时可以取消操作》一文中使用到了多线程编程,在这里做个笔记。

我们继续使用《再谈委托——同步、异步、Lambda 表达式和内置委托》一文的示例代码为本文示例。原文中使用异步委托调用同步方法,即:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click'暂时移除Button1按钮点击事件RemoveHandler Button1.Click, AddressOf Button1_Click'******************************************Dim method As MethodInvoker = Sub()'模拟长时间工作代码For i As Integer = 0 To 100'模拟长时间工作Threading.Thread.Sleep(100)'显示工作进度Dim Actiondelegate As Action(Of Integer) = Sub(int)Me.Label1.Text = int.ToString & "%"End SubMe.Label1.Invoke(Actiondelegate, i)NextEnd Submethod.BeginInvoke(Nothing, Nothing)'******************************************'工作结束后记得恢复Button1按钮点击事件AddHandler Button1.Click, AddressOf Button1_ClickEnd Sub

现修改为线程,代码如下:

Private th As ThreadPrivate Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click'暂时移除Button1按钮点击事件RemoveHandler Button1.Click, AddressOf Button1_Click'******************************************th = New Thread(New ThreadStart(Sub()'模拟长时间工作代码For i As Integer = 0 To 100'模拟长时间工作Threading.Thread.Sleep(100)'显示工作进度Dim Actiondelegate As Action(Of Integer) = Sub(int)Me.Label1.Text = int.ToString & "%"End SubMe.Label1.Invoke(Actiondelegate, i)NextEnd Sub))th.Start()'******************************************'工作结束后记得恢复Button1按钮点击事件AddHandler Button1.Click, AddressOf Button1_ClickEnd Sub

运行代码,与异步委托效果一致,尝试运行中途关闭窗体,报错了:ponentModel.InvalidAsynchronousStateException:“调用方法时发生错误。 目标线程不再存在。”,如图:

这是因为Me.Label1.Invoke(Actiondelegate, i)代码需在主线程(UI线程)执行,而关闭窗体后主线程已经销毁了,但子线程th还在继续运行,所以报错。应该在关闭窗体的同时关闭子线程th。添加如下代码:

Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosingIf th.ThreadState <> ThreadState.Stopped Thenth.Abort()End IfEnd Sub

多点击几次按钮,还是会报错,可能是运行了多个子线程,但只关闭了一个,最好的办法是设置线程为后台线程,当主线程关闭时后台线程也会一同关闭,在th.Start()语句之前加入th.IsBackground = True即可。

以上是使用Lambda 表达式,你也可以使用AddressOf关联委托的方法。如下:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click'暂时移除Button1按钮点击事件RemoveHandler Button1.Click, AddressOf Button1_Click'******************************************th = New Thread(AddressOf aa)th.IsBackground = True '后台线程th.Start()'******************************************'工作结束后记得恢复Button1按钮点击事件AddHandler Button1.Click, AddressOf Button1_ClickEnd SubPrivate Sub aa()SyncLock lockObjFor i As Integer = 0 To 100'模拟长时间工作Threading.Thread.Sleep(100)'显示工作进度'Me.Label1.Text = i.ToString & "%"'修改为Dim Actiondelegate As Action(Of Integer) = New Action(Of Integer)(AddressOf bb)Me.Label1.Invoke(Actiondelegate, i)NextEnd SyncLockEnd SubPrivate Sub bb(ByVal int As Integer)'显示工作进度Me.Label1.Text = int.ToString & "%"End Sub

可见,使用多线程编程并没有想象中的那么难,其实与使用委托类似:

首先,你需引入命名空间:Imports System.Threading

其次,定义一个线程,很简单:Dim th As Thread

然后实例化,可以使用AddressOf或Lambda 表达式。th = New Thread(AddressOf 过程名)

然后使用Start方法运行线程:th.Start()

使用ThreadState或IsAlive属性监控线程状态,采用处理措施,如使用Abort方法关闭线程:th.Abort()

以下是线程常用的命令:

命令 含义

Start 引起线程开始运行

Sleep 暂停线程一段时间。格式:Thread.Sleep(毫秒数)

Suspend 线程到达安全点时暂停线程

Abort 停止线程

Resume 重新启动暂停的线程

Join 引起当前线程等待另一个线珵结果

下表是线程常用属性:

属性 值

IsAlive 如果线程是活动的,值为True

IsBackgroud 获取或设置一个布尔值,表示某个线程是否允许是后台线程

Name 获取或设置线程的名称

Priority 获取或设置一个操作系统用于区分线程调用的优先级

ApartmentState 获取或设置特定线程使用的线程模型

ThreadState 包含描述线程状态的值

有关线程下操作窗体及线程同步请参考《再谈委托——同步、异步、Lambda 表达式和内置委托》。

更多多线程编程博文,请参考:

1、使用开发多线程

2、多线程

3、线程的坎坷人生

4、【】多线程程序编写技术分析

5、官方帮助《托管线程处理》

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。