象和一个标志,用以跟踪后台操作是处于活动状态还是处于完成状态。
Private mController As New Controller(Me)
Private mActive As Boolean
然后,我们可以添加方法,以实现由 IClient 定义的接口。建议将这些方法放在 Region 中,以表示它们实现的是辅助接口:
#Region " IClient "
Private Sub TaskStarted(ByVal Controller As Controller) _
Implements IClient.Start
mActive = True
Label1.Text = "Starting"
Label2.Text = "0%"
ProgressBar1.Value = 0
ActivityBar1.Start()
End Sub
Private Sub TaskStatus(ByVal Text As String) _
Implements IClient.Display
Label1.Text = Text
Label2.Text = CStr(mController.Percent) & "%"
ProgressBar1.Value = mController.Percent
End Sub
Private Sub TaskFailed(ByVal e As Exception) _
Implements IClient.Failed
ActivityBar1.Stop()
Label1.Text = e.Message
MsgBox(e.ToString)
mActive = False
End Sub
Private Sub TaskCompleted(ByVal Cancelled As Boolean) _
Implements IClient.Completed
Label1.Text = "Completed"
Label2.Text = CStr(mController.Percent) & "%"
ProgressBar1.Value = mController.Percent
ActivityBar1.Stop()
mActive = False
End Sub
#End Region
请注意,这一段代码中的所有内容均与线程无关,其中的每一部分代码都可以在我们得知后台操作的状态时做出相应的响应。每次响应后,我们都会更新显示以表明进程的状态和完成百分比(以文字的形式或通过 ProgressBar 显示),并启动和停止 ActivityBar 控件。
mActive 标志非常重要。如果用户在辅助线程处于活动状态时关闭窗体,应用程序可能会挂起或变得不稳定。要防止出现这种情况,我们可以打断窗体的 Closing 事件并取消关闭尝试(如果后台进程处于活动状态)。
Private Sub Form1_Closing(ByVal sender As Object, _
ByVal e As System.ComponentModel.CancelEventArgs) _
Handles MyBase.Closing
e.Cancel = mActive
End Sub
我们还可以选择在这种情况下初始化取消操作,但是这取决于特定的应用程序要求。
其余的代码都是为了实现按钮的 Click 事件。
Private Sub btnStart_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnStart.Click
mController.Start(New Worker(2000000, 100))
End Sub
Private Sub btnStop_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnStop.Click
Label1.Text = "Ca