由于近期在研究防止窗体假死该如何给长时间运行的方法加一个等待的画面,需要用到异步委托和Lambda 表达式,所以紧急饿补了相关内容,现把学习感受记录备查。
相关博文:《异步委托实现等待窗体(loading界面),执行任务超时可以取消操作》
本文主要是简化《程序长时间执行任务时窗体会失去响应造成假死避免重复点击按钮的解决思路》一文代码,更突出问题。
一、窗体假死
新建一个windows窗体应用程序,在窗体里拉入一个按钮Button和一个Label控件,为按钮单击事件添加如下代码:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'暂时移除Button1按钮点击事件
RemoveHandler Button1.Click, AddressOf Button1_Click
'******************************************
'模拟长时间工作代码
For i As Integer = 0 To 100
'模拟长时间工作
Threading.Thread.Sleep(100)
'显示工作进度
Me.Label1.Text = i.ToString & "%"
Next
'******************************************
'工作结束后记得恢复Button1按钮点击事件
AddHandler Button1.Click, AddressOf Button1_Click
End Sub
执行循环时窗体不能拖动,点击按钮无反应,Label也不能实时显示工作进度,直到循环结束直接显示100%,窗体处于假死状态。
二、同步委托
为了便于理解,我把长时间运行的代码封装到一个方法里,然后在按钮单击事件里调用该方法。
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'暂时移除Button1按钮点击事件
RemoveHandler Button1.Click, AddressOf Button1_Click
'******************************************
'调用长时间工作代码
Call aa()
'******************************************
'工作结束后记得恢复Button1按钮点击事件
AddHandler Button1.Click, AddressOf Button1_Click
End Sub
Private Sub aa()
For i As Integer = 0 To 100
'模拟长时间工作
Threading.Thread.Sleep(100)
'显示工作进度
Me.Label1.Text = i.ToString & "%"
Next
End Sub
改用同步委托(Delegate.Invoke)调用方法:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'暂时移除Button1按钮点击事件
RemoveHandler Button1.Click, AddressOf Button1_Click
'******************************************
'调用长时间工作代码
'Call aa()
'改用委托调用方法
Dim method As Meth