进度条在加载其他表单时冻结
Progressbar freezing while the other form loading
我有 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时进度条开始但卡在开头
有什么解决办法吗?
尝试使进程异步,据我了解,计时器滴答已经是异步的,但在 form1 中,您可以在任务中使用该代码
Me.Hide
Task.Run(Function() Form2.Show())
Form3.Show()
自从我开始使用 C# 编程以来,我在 vb.net 上从未达到过这一步,但这应该可以解决问题
如果您是编程新手,那么这可能有点令人困惑,但答案是将代码从 Form3
的 Load
事件处理程序推送到 Async
方法中并等待它。您的 UI 冻结是因为您在 UI 线程上同步工作。您需要显式使用辅助线程或使用 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
实际上,这可能比必要的更复杂,这应该可以正常工作:
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
重读你的问题后,你可能需要做的是让你的异步方法成为一个函数来检索和 returns 来自网页或其他内容的数据,然后将该数据加载到你的 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
方法 returns a Task(Of DataTable)
,即异步执行 returns a DataTable
的函数的 Task
。在 Load
事件处理程序中,您调用该方法并等待 Task
,这意味着您的代码将等待 Task
执行并返回其数据,但不会阻塞 [=41] =] 线程作为同步调用就可以了。同步等价物是这样的:
Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
DataGridView1.DataSource = GetData()
End Sub
Private Function GetData() As DataTable
Dim table As New DataTable
'Populate table here.
Return table
End Function
我有 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时进度条开始但卡在开头
有什么解决办法吗?
尝试使进程异步,据我了解,计时器滴答已经是异步的,但在 form1 中,您可以在任务中使用该代码
Me.Hide
Task.Run(Function() Form2.Show())
Form3.Show()
自从我开始使用 C# 编程以来,我在 vb.net 上从未达到过这一步,但这应该可以解决问题
如果您是编程新手,那么这可能有点令人困惑,但答案是将代码从 Form3
的 Load
事件处理程序推送到 Async
方法中并等待它。您的 UI 冻结是因为您在 UI 线程上同步工作。您需要显式使用辅助线程或使用 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
实际上,这可能比必要的更复杂,这应该可以正常工作:
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
重读你的问题后,你可能需要做的是让你的异步方法成为一个函数来检索和 returns 来自网页或其他内容的数据,然后将该数据加载到你的 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
方法 returns a Task(Of DataTable)
,即异步执行 returns a DataTable
的函数的 Task
。在 Load
事件处理程序中,您调用该方法并等待 Task
,这意味着您的代码将等待 Task
执行并返回其数据,但不会阻塞 [=41] =] 线程作为同步调用就可以了。同步等价物是这样的:
Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
DataGridView1.DataSource = GetData()
End Sub
Private Function GetData() As DataTable
Dim table As New DataTable
'Populate table here.
Return table
End Function