0

我有 3 个表格;

表格 1 - 主表格

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 加载时开始冻结

有什么解决办法吗?

4

2 回答 2

1

如果您是编程新手,那么这可能有点令人困惑,但答案是将代码从Load事件处理程序推Form3送到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方法返回 a Task(Of DataTable),即Task异步执行返回 a 的函数的 a DataTable。在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-18T12:41:56.160 回答
1

尝试使过程异步,据我了解,计时器滴答已经是异步的,但是在 form1 中,您可以使用可以在 Task 中包含该代码

Me.Hide
Task.Run(Function() Form2.Show())
Form3.Show()

自从我开始在 c# 上编程以来,我从未在 vb.net 上达到过这么远,但这应该可以解决问题

于 2018-10-18T12:39:32.287 回答