Vb.net 在运行workerasync之后,如何阻止代码执行下一行,直到它完成?

Vb.net 在运行workerasync之后,如何阻止代码执行下一行,直到它完成?,vb.net,asynchronous,backgroundworker,Vb.net,Asynchronous,Backgroundworker,我的VB.NET(WPF)应用程序具有下拉列表,其中包含州及其城市的名称。我使用循环遍历选定的州及其城市,并执行一些有关城市的函数。我为循环中的每个城市检查N个网页,并使用BackGroundWorker将一些结果填充到数据网格中 但是,由于我在循环中使用了一个backgroundworker,因此它会被执行并发送到后台,代码也会继续前进。我需要代码等到backgroundworker(RunWorkerAsync)完成后才能转到下一行。当我在一个城市使用它时,它工作得非常好,但是当我在一个城市

我的VB.NET(WPF)应用程序具有下拉列表,其中包含州及其城市的名称。我使用循环遍历选定的州及其城市,并执行一些有关城市的函数。我为循环中的每个城市检查N个网页,并使用BackGroundWorker将一些结果填充到数据网格中

但是,由于我在循环中使用了一个backgroundworker,因此它会被执行并发送到后台,代码也会继续前进。我需要代码等到backgroundworker(RunWorkerAsync)完成后才能转到下一行。当我在一个城市使用它时,它工作得非常好,但是当我在一个城市列表的循环中使用它时,它只是在backgroundworker之后继续执行下一行,循环继续进行

我以前对此进行过研究,解决方案给我的唯一选择是引入一个在代码中完成的Runworker。这意味着我必须将代码分为两部分,然后将我想要在之后执行的内容放在RunWorkerCompleted中。这会循环工作吗?下面是一些伪代码:

For i as integer = 0 to cityCount

Dim city as string = cbCity.SelectedValue.ToString()
worker.RunWorkerAsync
worker.RunWorkerCompleted
cbCity.SelectedIndex += 1

Next
事情是这样的。当worker.RunWorkerAsync仍在运行时,上述伪代码不会运行worker.RunWorkerCompleted?它是否会等待worker.RunWorkerAsync完成并完成,然后执行worker.RunWorkerCompleted?我使用BackgroundWorker填充UI而不冻结它,city变量在每次迭代中都会更新,并在RunWorkerAsync中使用。因此,本质上,我正在尝试完全执行worker.RunWorkerAsync,然后转到下一行并继续循环


如果我的语言不通,我很抱歉。我对此进行了研究,并尝试了几种方法,我之所以来到这里,是因为它们都不起作用。由于一些版权问题,我无法共享完整的代码,但我很乐意提供更多信息。

我不知道这是否是您的选择:

'Iteration Sub
Private Sub MyStatus()
    'Here your code iteration
    For i As Integer = 1 To 10000
        BackgroundWorker1.ReportProgress(CInt(100 * i / 10000))
        If BackgroundWorker1.CancellationPending = True Then Exit For
    Next
End Sub

'For begin and stop Async
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
    BackgroundWorker1.CancelAsync()
    Try
        BackgroundWorker1.RunWorkerAsync()
    Catch ex As Exception
    End Try
End Sub

'To Call the iteration
Private Sub bw1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    MyStatus()
End Sub

'To Monitor the progress
Private Sub bw1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    Me.ProgressBar1.Value = e.ProgressPercentage
End Sub

'If any information need to indicate that the iteration is complete
Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
End Sub

RunWorkerCompleted在RunWorkerAsync完成时自动调用(请参阅文档)

循环应该在BGW中,以及您希望在每次迭代结束时运行的代码



(请注意,可以将对象作为其第二个参数,因此如果要传递合适的类,则可以向ProgressChanged处理程序发送任何需要的内容。)

如果需要等待,则使用BGW没有意义,最好直接运行代码。正确的用法确实是将需要完成作业的任何代码移动到RunWorkerCompleted事件处理程序中。如果您想让一切都在一个地方,那么您需要切换到Task并使用async/await.RunWorkerCompleted在RunWorkerAsync完成时自动调用(请参阅)。在我看来,循环应该在BGW中,以及您希望在每次迭代结束时运行的代码。。。。请注意,可以将一个对象作为其第二个参数,因此如果要传递一个合适的类,则可以向ProgressChanged处理程序发送任何需要的内容。@HansPassant I无法消除BGW,因为代码没有正确更新UI,并且在更新datagrid时不断冻结UI。在Moverover中,Async/Wait只会使线程休眠,并且仍然会导致UI冻结。我错了吗?@AndrewMorton我将整个代码放在BGW中,现在它等待函数完成执行,然后再转到下一行代码。这是你在第一次评论中提出的建议,效果不错。