Vb.net 在运行workerasync之后,如何阻止代码执行下一行,直到它完成?
我的VB.NET(WPF)应用程序具有下拉列表,其中包含州及其城市的名称。我使用循环遍历选定的州及其城市,并执行一些有关城市的函数。我为循环中的每个城市检查N个网页,并使用BackGroundWorker将一些结果填充到数据网格中 但是,由于我在循环中使用了一个backgroundworker,因此它会被执行并发送到后台,代码也会继续前进。我需要代码等到backgroundworker(RunWorkerAsync)完成后才能转到下一行。当我在一个城市使用它时,它工作得非常好,但是当我在一个城市列表的循环中使用它时,它只是在backgroundworker之后继续执行下一行,循环继续进行 我以前对此进行过研究,解决方案给我的唯一选择是引入一个在代码中完成的Runworker。这意味着我必须将代码分为两部分,然后将我想要在之后执行的内容放在RunWorkerCompleted中。这会循环工作吗?下面是一些伪代码:Vb.net 在运行workerasync之后,如何阻止代码执行下一行,直到它完成?,vb.net,asynchronous,backgroundworker,Vb.net,Asynchronous,Backgroundworker,我的VB.NET(WPF)应用程序具有下拉列表,其中包含州及其城市的名称。我使用循环遍历选定的州及其城市,并执行一些有关城市的函数。我为循环中的每个城市检查N个网页,并使用BackGroundWorker将一些结果填充到数据网格中 但是,由于我在循环中使用了一个backgroundworker,因此它会被执行并发送到后台,代码也会继续前进。我需要代码等到backgroundworker(RunWorkerAsync)完成后才能转到下一行。当我在一个城市使用它时,它工作得非常好,但是当我在一个城市
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中,现在它等待函数完成执行,然后再转到下一行代码。这是你在第一次评论中提出的建议,效果不错。