VB.net 继续
VB.net ContinueWith
我有这段代码循环遍历列表中的所有帐户,然后使用每个帐户的任务对帐户执行某些操作以加快流程。每次程序完成此操作时,我都希望用户界面更新进度条。我以前使用过 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
仍然不起作用不知道为什么?
Now I know this can be done using a background worker but this isn't the best way of making your application multithreaded
有点。
BackgroundWorker 是单独 运行 许多不同任务的糟糕方法。没有人愿意为每个任务处理一个单独的 BackgroundWorker 组件。但是 one BackgroundWorker 是一种 很棒的 方法,它只产生一个额外的线程来管理所有其他任务并更新进度条。这是一个简单的解决方案。
无论哪种方式,您肯定要做的一件事是移动代码以更新单个任务中的 ProgressBar。将它放在任务中违反了关注点分离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 这里的问题说明了我们关心关注点分离的一个原因。一旦我解决了这个问题,代码就会变得 简单得多 并且令人沮丧的错误就会消失。
我有这段代码循环遍历列表中的所有帐户,然后使用每个帐户的任务对帐户执行某些操作以加快流程。每次程序完成此操作时,我都希望用户界面更新进度条。我以前使用过 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
仍然不起作用不知道为什么?
Now I know this can be done using a background worker but this isn't the best way of making your application multithreaded
有点。
BackgroundWorker 是单独 运行 许多不同任务的糟糕方法。没有人愿意为每个任务处理一个单独的 BackgroundWorker 组件。但是 one BackgroundWorker 是一种 很棒的 方法,它只产生一个额外的线程来管理所有其他任务并更新进度条。这是一个简单的解决方案。
无论哪种方式,您肯定要做的一件事是移动代码以更新单个任务中的 ProgressBar。将它放在任务中违反了关注点分离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 这里的问题说明了我们关心关注点分离的一个原因。一旦我解决了这个问题,代码就会变得 简单得多 并且令人沮丧的错误就会消失。