Reputation: 1599
So I'm processing records. I'm using a task to process each record. My issue is that my program is completing before all tasks complete. Anyone any thoughts on what I'm doing wrong here?
Dim task As Task
Try
'Keep looping until no more requests to run have been made
Do
Dim controller As New Controller()
Dim record As Record = controller.GetNextRecord()
If record IsNot Nothing Then
'Use Task!
task = Task.Factory.StartNew(Sub() controller.ProcessRecord(record), TaskCreationOptions.LongRunning)
CalledWhenBusy = True
End If
TryAgain:
Loop Until ProcessAgain() = False
Catch ex As System.Net.WebException
logger.ErrorException("unable to connect to remoting server", ex)
Finally
logger.Info("Processed all records.. now about to wait for all tasks to complete")
'Wait till all tasks have stopped running
Task.WaitAll(task)
logger.Info("Processed all records.. All tasks have completed")
'The dispatcher has finished for now so clean up
Me.StopUsing()
End Try
Private Function ProcessAgain() As Boolean
If CalledWhenBusy Then
'Reset the flag and exit with true
CalledWhenBusy = False
Return True
End If
Return False
End Function
UPDATE
I've resolved my issue by using a list of tasks as suggested by @HansPassant and @usr
The reason for not using Foreach, is that more records can be added while processing.. hence the do while loop...
Thank you for your help.
Dim taskList = New List(Of Task)()
Try
'Keep looping until no more requests to run have been made
Do
Dim controller As New Controller()
Dim record As Record = controller.GetNextRecord()
If record IsNot Nothing Then
'Use Task!
taskList.Add(Task.Factory.StartNew(Sub() controller.ProcessRecord(record)))
CalledWhenBusy = True
End If
TryAgain:
Loop Until ProcessAgain() = False
Catch ex As System.Net.WebException
logger.ErrorException("unable to connect to remoting server", ex)
Finally
logger.Info("Processed all records.. now about to wait for all tasks to complete")
'Wait till all tasks have stopped running
Task.WaitAll(taskList.ToArray())
logger.Info("Processed all records.. All tasks have completed")
'The dispatcher has finished for now so clean up
Me.StopUsing()
End Try
Upvotes: 0
Views: 1274
Reputation: 171246
Task.WaitAll(task)
is just waiting for one task. Where are the others? Did you even store them? Not apparent from this code.
Ideally, you transform this code so that it can make use of Parallel.ForEach
. You need to put the work items into IEnumerable
format for that to work. For example, add them to a List
and feed the list to Parallel.ForEach
.
Upvotes: 2