首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Progressbar冻结,而其他表单正在加载

Progressbar冻结,而其他表单正在加载
EN

Stack Overflow用户
提问于 2018-10-18 20:29:30
回答 2查看 1.2K关注 0票数 0

我有3种形式;

Form1 -主窗体

Form2 -子窗体(包含进度条和计时器)

Form3 -包含大量内容的子窗体,需要时间进行加载(例如在窗体加载事件中解析网页数据并将其写入Datagridview )

我需要在form3加载时显示运行进度条的form2

我在Form1上有以下代码;

代码语言:javascript
复制
Me.Hide
Form2.Show()
Form3.Show()

表格2中的代码;

代码语言:javascript
复制
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加载时,问题是进度条开始启动,但在开始时冻结

有什么解决方案吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-18 20:41:56

如果您是编程新手,那么这可能有点令人困惑,但答案是将代码从Form3Load事件处理程序推送到Async方法中,并等待它。您的UI冻结,因为您正在同步地在UI线程上执行工作。您需要显式使用辅助线程或使用Async/Await。这一点:

代码语言:javascript
复制
Private Sub Form3_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    'Do some work.
End Sub

会变成这样:

代码语言:javascript
复制
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

实际上,这可能比必要的更复杂,这应该可以很好地工作:

代码语言:javascript
复制
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中,例如

代码语言:javascript
复制
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线程。同步等效项是这样的:

代码语言:javascript
复制
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
票数 1
EN

Stack Overflow用户

发布于 2018-10-18 20:39:32

尝试使进程异步,据我所知,计时器滴答已经是异步的,但在form1中,您可以在任务中使用该代码

代码语言:javascript
复制
Me.Hide
Task.Run(Function() Form2.Show())
Form3.Show()

自从我开始在c#上编程以来,我从未在vb.net上走到这一步,但这篇文章应该可以做到这一点

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52874051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档