-2

我有这段代码循环遍历列表中的所有帐户,然后使用每个帐户的任务对帐户执行某些操作,以加快流程。每次程序完成这个动作,我希望用户界面更新进度条。我以前使用过 Invoke,但它不是最好的选择,我无法让它工作。现在我知道这可以使用后台工作人员来完成,但这不是使您的应用程序多线程的最佳方式,所以我使用了这个。而不是调用我听说 ContinueWith 但我似乎无法让它工作,我没有收到错误消息,只是一个红色下划线。代码:

progressBar.Value = 0
    Dim tasks As New List(Of Task)()
    For Each account In combos
        Dim t As Task = Task.Run(Sub()
                                     While checked = False
                                         If proxies.Count = 0 Then
                                             Exit Sub
                                             'Also can't think of a good way to stop searching through accounts when there are no proxies left in my queue.
                                         End If
                                         Dim proxy As New WebProxy(proxies(0))
                                         proxies.TryDequeue(0)
                                         'Do something
                                     End While
                                     checkedAmount += 1
                                     Dim progress As Integer = ((checkedAmount / combos.Count) * 100)
                                     Task.ContinueWith(progressBar.Value = progress, TaskScheduler.FromCurrentSynchronizationContext()) 'Error here
                                 End Sub)
        tasks.Add(t)
    Next
    Task.WaitAll(tasks.ToArray())

我没有得到如下所示的错误代码: 在此处输入图像描述

我也尝试过在这些东西之后放一个子,但这没有任何结果。感谢您提前提供任何帮助。

使用调用尝试更新:

 Private Delegate Sub UpdateProgressBarDelegate(ByVal progressBarUpdate As ProgressBar, ByVal value As Integer)

Dim checkedAmount As Integer = 0
Dim checked As Boolean = False
Private Sub startBtn_Click(sender As Object, e As EventArgs) Handles startBtn.Click
    progressBar.Value = 0
    Dim tasks As New List(Of Task)()
    For Each account In combos
        Dim t As Task = Task.Run(Sub()
                                     While checked = False
                                         proxies.TryDequeue(0)
                                         'do stuff
                                     End While
                                     checkedAmount += 1
                                     Dim progress As Integer = ((checkedAmount / combos.Count) * 100)
                                     If Me.InvokeRequired = True Then
                                         Me.Invoke(New UpdateProgressBarDelegate(AddressOf UpdateProgressBar), progressBar, progress)
                                     Else
                                         UpdateProgressBar(progressBar, progress)
                                     End If
                                     'Task.ContinueWith(progressBar.Value = progress, TaskScheduler.FromCurrentSynchronizationContext())
                                 End Sub)
        tasks.Add(t)
    Next
    Task.WaitAll(tasks.ToArray())
End Sub

Private Sub UpdateProgressBar(ByVal ProgressBarUpdate As ProgressBar, progress As Integer)
    progressBar.Value = progress
End Sub

仍然不工作不知道为什么?

4

1 回答 1

3

现在我知道这可以使用后台工作人员来完成,但这不是使您的应用程序多线程的最佳方式

有点。

BackgroundWorker 是单独运行许多不同任务的糟糕方法。没有人愿意为每个任务处理一个单独的 BackgroundWorker 组件。但是一个BackgroundWorker 是一种很好的方式,可以只产生一个额外的线程来管理所有其他任务并更新进度条。这是一个简单的解决方案。

无论哪种方式,您肯定要做的一件事就是移动代码以更新各个任务之外的 ProgressBar。将其放在 Tasks 中违反了关注点分离1。一旦你这样做了,你还需要将调用更改WaitAll()WaitAny()在一个知道你有多少任务的循环中使用,这样你仍然可以在每个任务完成时更新 ProgressBar。这也可能会产生解决您当前问题的副作用。

Private Async Sub startBtn_Click(sender As Object, e As EventArgs) Handles startBtn.Click

    Dim tasks As New List(Of Task)()
    For Each account In combos
       Dim t As Task = Task.Run(Sub()
                                 While Not checked
                                     proxies.TryDequeue(0)
                                     'do stuff
                                 End While
                               End Sub)
        tasks.Add(t)
    Next


    progressBar.Value = 0
    For i As Integer = 1 To tasks.Count 
        Dim t = Await Task.WhenAny(tasks) 
        tasks.Remove(t)
        progressBar.Value  = (i / combos.Count) * 100
    Next i
End Sub

1 这里的问题说明了我们关心关注点分离的一个原因。一旦我解决了这个问题,代码就会变得简单得多,令人沮丧的错误就会消失。

于 2017-10-12T20:51:27.627 回答