Reputation: 364
I need to run, lets say, 20 parallel tasks. The task function that is being called is a long running function and can generate errors. I wanted to detect that from the caller and revive the task.
While I understand that handling the exception "inside the task" and rerunning the task is a solution, I was also thinking if there are means to detect this from the caller itself and run the failing task again. When I revive the task it should fall under the bucket of 20 tasks running so that the calling process continues to wait for all the tasks running including the new revived task via Await Task.WhenAll(tasks)
Here is the code on the caller side that creates 20 different task and waits for all of them to finish.
Try
watch = New Stopwatch
watch.Start()
cs = New CancellationTokenSource
Timer1.Enabled = True
Dim tasks = Enumerable.Range(1, 20).Select(Function(i) Task.Run(Function() GetAndProcessMessagesAsync(cs.Token)))
Await Task.WhenAll(tasks)
Catch ex As Exception
MsgBox(ex.Message)
Timer1.Enabled = False
End Try
PS: I have checked the below links for a solution but did not find something suitable that I could try. But definitely would think another method could be to use the TaskContinuationOptions
option but am really not sure how and where that would fit in my code above.
catching parallel tasks if they stop prematurely
Upvotes: 0
Views: 55
Reputation: 244777
I think that doing it inside the Task
is the best option, but that doesn't mean you have to change GetAndProcessMessagesAsync
. The code could look like this:
Async Function RetryAsync(func As Func(Of Task)) As Task
While True
Try
Await func()
Catch
' TODO: don't catch all exceptions all the time
End Try
End While
End Function
…
Dim tasks = Enumerable.Range(1, 20).Select(
Function(i) Task.Run(
Function() RetryAsync(
Function() GetAndProcessMessagesAsync(cs.Token))))
Also, if GetAndProcessMessagesAsync
is truly asynchronous, you might not need that Task.Run
.
Upvotes: 1