我有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加载时,问题是进度条开始启动,但在开始时冻结
有什么解决方案吗?
发布于 2018-10-18 20:41:56
如果您是编程新手,那么这可能有点令人困惑,但答案是将代码从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
在重读了你的问题之后,你可能需要做的是让你的异步方法成为一个从网页或其他地方检索和返回数据的函数,然后你将这些数据同步加载到你的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)
,即异步执行返回DataTable
的函数的Task
。在Load
事件处理程序中,您调用该方法并等待Task
,这意味着您的代码将等待,直到Task
执行并返回其数据,但不会像同步调用那样阻塞UI线程。同步等效项是这样的:
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
发布于 2018-10-18 20:39:32
尝试使进程异步,据我所知,计时器滴答已经是异步的,但在form1中,您可以在任务中使用该代码
Me.Hide
Task.Run(Function() Form2.Show())
Form3.Show()
自从我开始在c#上编程以来,我从未在vb.net上走到这一步,但这篇文章应该可以做到这一点
https://stackoverflow.com/questions/52874051
复制相似问题