Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 当另一个窗体加载时,Progressbar冻结_Vb.net_Timer_Progress Bar_Form Load - Fatal编程技术网

Vb.net 当另一个窗体加载时,Progressbar冻结

Vb.net 当另一个窗体加载时,Progressbar冻结,vb.net,timer,progress-bar,form-load,Vb.net,Timer,Progress Bar,Form Load,我有3张表格 表格1-主要表格 Form2-子表单(包含进度条和计时器) Form3-包含大量内容的子表单,加载需要时间(如解析网页中的数据并在表单加载事件中将其写入Datagridview) 我需要在form3加载时显示运行进度条的form2 我在表格1中有以下代码 Me.Hide Form2.Show() Form3.Show() 表格2的代码 Public Class Form2 Private Sub Form2_Load(sender As Object, e As EventArg

我有3张表格

表格1-主要表格

Form2-子表单(包含进度条和计时器)

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

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

我在表格1中有以下代码

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
公共类表单2
私有子表单2_Load(发送方作为对象,e作为事件参数)处理MyBase.Load
LoadingTimer.Enabled=True
端接头
私有子加载timer_Tick(发送方作为对象,e作为事件参数)处理加载timer.Tick

如果MyProgressBar.Value尝试使进程异步,我的理解是计时器勾号已经是异步的,但在形式1中,您可以使用在任务中包含该代码

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

自从我开始在c#上编程以来,我在vb.net上从未达到过这么高的水平,但这应该可以达到目的

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

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

自从我开始在c#上编程以来,我在vb.net上从来没有达到过这么高的水平,但这应该可以做到。如果你是编程新手,那么这可能有点令人困惑,但答案是将代码从
Form3
加载
事件处理程序推送到
异步
方法中,然后等待它。您的UI冻结是因为您在UI线程上同步工作。您需要显式使用辅助线程或使用
Async
/
wait
。这:

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
方法返回一个
任务(数据表的)
,即一个
任务
,该任务异步执行一个返回
数据表的函数。在
加载
事件处理程序中,调用该方法并等待
任务
,这意味着您的代码将等待
任务
执行并返回其数据,但不会像同步调用那样阻塞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

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

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
方法返回一个
任务(数据表的)
,即一个
任务
,该任务异步执行一个返回
数据表的函数。在
加载
事件处理程序中,调用该方法并等待
任务
,这意味着您的代码将等待
任务
执行并返回其数据,但不会像同步调用那样阻塞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

您不应该在不同的线程/任务中修改UI元素。这样做最终会破坏一切,即使它现在起作用。所有与UI相关的工作都应该只在UI线程上完成。你的想法是正确的,但你的代码是错误的。只将繁重的处理和其他非UI工作移动到任务,而不是整个表单。@nalnpir,您好,您的代码出现错误,请重新检查好吗?请尝试使用Sub()代替Function()@VisualIncent well老实说你是对的,我会在我的c#代码中使用Invoke,我不认为像这样的简单任务会产生任何错误,但是阿里,你应该对Invoke方法的用法进行更多的调查。@nalnpir谢谢你,但你能再给我一个提示吗?如果你不介意的话,可以使用C语言,你不应该在不同的线程/任务中修改UI元素。这样做最终会破坏一切,即使它现在起作用。所有与UI相关的工作都应该只在UI线程上完成。你的想法是正确的,但你的代码是错误的。只将繁重的处理和其他非UI工作移动到任务,而不是整个表单。@nalnpir,您好,您的代码出现错误,请重新检查好吗?请尝试使用Sub()代替Function()@VisualIncent well老实说你是对的,我会在我的c#代码中使用Invoke,我不认为像这样的简单任务会产生任何错误,但是阿里,你应该对Invoke方法的用法进行更多的调查。@nalnpir谢谢你,但你能再给我一个提示吗?如果你不介意我的新手级问题的话,可能是C#######但我应该为“在Async Sub做一些工作,form2.show是否足够或需要在form3中添加计时器?”添加什么?@Ali:Inside
Task.Run()
你应该放置所有与UI(用户界面)不交互的繁重的处理代码。任何直接涉及访问表单或其任何控件的操作都需要在
Task.Run()
@Ali之前或之后完成。如果您必须访问任务内部的UI,则可以使用
Control.Invoke()
从UI线程访问和返回信息(有关此操作的更多信息,请参阅访问UI线程)。但要当心!仅访问作为