BackgroundWorkerQueue.
When you have receive list of URL to downloads (in cycle or after parser/webscraper was finished), you have only one way to download this list without freezing GUI of desktop apps - to use class, similar to this.
1: Imports System.ComponentModel
2:
3: Public Class BackgroundWorkerQueue
4:
5: Public Property ContinueOnError As Boolean
6: Private Property Queue As Queue(Of QueuedWorker)
7: Private Property DoWorkEventHandler As DoWorkEventHandler
8: Public Event QueueFinished()
9:
10: Public Sub New()
11: Me.Queue = New Queue(Of QueuedWorker)()
12: End Sub
13:
14: Public Sub Add(ByVal Worker As BackgroundWorker, ByVal Argument As Object, DoWorkEventHandler1 As DoWorkEventHandler)
15: DoWorkEventHandler = DoWorkEventHandler1
16: Me.Queue.Enqueue(New QueuedWorker(Worker, Argument))
17: End Sub
18:
19: Public Sub RunWorkerAsync()
20: Debug.Print("BackgroundWorker.Run(), {0} items in queue.", Me.Queue.Count)
21: Dim Q As QueuedWorker = Me.Queue.Dequeue()
22: AddHandler Q.Worker.RunWorkerCompleted, New RunWorkerCompletedEventHandler(AddressOf Me.Completed)
23: AddHandler Q.Worker.DoWork, DoWorkEventHandler
24: Q.Worker.RunWorkerAsync(Q.Argument)
25: End Sub
26:
27: Private Sub Completed(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
28: Debug.Print("BackgroundWorker.Completed()")
29: Dim Worker As BackgroundWorker = TryCast(sender, BackgroundWorker)
30: If Worker IsNot Nothing Then
31: RemoveHandler Worker.RunWorkerCompleted, AddressOf Me.Completed
32: RemoveHandler Worker.DoWork, DoWorkEventHandler
33: If (Me.ContinueOnError OrElse e.[Error] Is Nothing) AndAlso Me.Queue.Count > 0 Then
34: Me.RunWorkerAsync()
35: ElseIf Queue.Count = 0 Then
36: RaiseEvent QueueFinished()
37: End If
38: End If
39: End Sub
40: End Class
41:
42: Public Class QueuedWorker
43: Public Property Argument As Object
44: Public Property Worker As BackgroundWorker
45:
46: Public Sub New()
47: End Sub
48:
49: Public Sub New(ByVal Worker1 As BackgroundWorker, ByVal Argument1 As Object)
50: Worker = Worker1
51: Argument = Argument1
52: End Sub
53: End Class
Use this class at this pattern:
...
306: Dim BGWorkerQueue As New BackgroundWorkerQueue
307: AddHandler BGWorkerQueue.QueueFinished, AddressOf BGWorkerQueueFinished
308: Dim BGW3 As New BackgroundWorker
309: For Each Link In LinkCollections
...
311: BGWorkerQueue.Add(BGW3, URL, AddressOf BGW3_DoWork)
312: Next
313: BGWorkerQueue.RunWorkerAsync()
314: End If
315: End If
316: End Sub
317:
319: Private Sub BGW3_DoWork(sender As Object, e As DoWorkEventArgs)
...
327: Download(e.Argument, ...)
...
330: End Sub
...:
342: Sub BGWorkerQueueFinished()
...
353: End Sub
354: