我有3种形式;
Form1-主表单
Form2-子表单(包含进度条和计时器)
Form3-包含大量内容的子表单需要花费一些时间来加载(例如从网页中解析数据并将其在表单加载事件中写入Datagridview)
我需要在加载form3时显示运行进度条的form2
我在Form1上有以下代码;
Me.Hide
Form2.Show()
Form3.Show()
表2中的代码;
Public Class Form2
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
LoadingTimer.Enabled = True
End Sub
Private Sub LoadingTimer_Tick(sender As Object, e As EventArgs) Handles LoadingTimer.Tick
If MyProgressBar.Value <= MyProgressBar.Maximum - 1 Then
MyProgressBar.Value += 10
End If
If MyProgressBar.Value = 100 Then
LoadingTimer.Enabled = False
Me.Close()
End If
If Label1.ForeColor = Color.LimeGreen Then
Label1.ForeColor = Color.White
Else
Label1.ForeColor = Color.LimeGreen
End If
End Sub
End Class
问题是进度栏开始但在加载Form3时开始冻结。
有解决方案的想法吗?
答案 0 :(得分:1)
尝试使该过程异步,据我了解,计时器刻度已经是异步的,但在form1中,您可以使用可以将代码包含在Task中
Me.Hide
Task.Run(Function() Form2.Show())
Form3.Show()
自从我开始使用C#编程以来,我从未在vb.net上达到这一目标,但这应该可以解决问题
答案 1 :(得分:1)
如果您是编程的新手,那么这可能会有些混乱,但是答案是将代码从Load
的{{1}}事件处理程序推入Form3
方法中并等待它。您的UI冻结,因为您正在UI线程上同步进行工作。您需要显式使用辅助线程或使用Async
/ Async
。这个:
Await
将成为这个:
Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Do some work.
End Sub
实际上,这可能比必要的要复杂,这应该可以正常工作:
Private Async Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Await DoWork()
End Sub
Private Async Function DoWork() As Task
Await Task.Run(Sub()
'Do some work.
End Sub).ConfigureAwait(False)
End Function
重新阅读您的问题后,您可能需要做的是使async方法成为一个函数,该函数从网页或其他任何东西检索并返回数据,然后将这些数据同步加载到Private Async Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Await Task.Run(Sub()
'Do some work.
End Sub).ConfigureAwait(False)
End Sub
中,例如
DataGridView
因此,Private Async Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
DataGridView1.DataSource = Await GetDataAsync()
End Sub
Private Async Function GetDataAsync() As Task(Of DataTable)
Return Await Task.Run(Function()
Dim table As New DataTable
'Populate table here.
Return table
End Function).ConfigureAwait(False)
End Function
方法返回GetDataAsync
,即Task(Of DataTable)
,它异步执行返回Task
的函数。在DataTable
事件处理程序中,您调用该方法并等待Load
,这意味着您的代码将等待Task
执行并返回其数据,但不会阻塞UI线程,因为同步调用即可。同步等效项为:
Task