Currenly using the following code to wait for a collection of tasks to complete. However, I now have a situation where I want to be able to cancel/abort the WhenAll call, via a cancellation token preferably. How would I go about that?
Dim TaskCollection As New List(Of Tasks.Task)
For x As Integer = 1 To Threads
Dim NewTask As Tasks.Task = TaskHandler.Delegates(DelegateKey).Invoke(Me, Proxies, TotalParams).ContinueWith(Sub() ThreadFinished())
TaskCollection.Add(NewTask)
Next
Await Tasks.Task.WhenAll(TaskCollection)
I'm assuming it's going to but something along the lines of the next bit of code, but I'm not sure what would go in 'XXX'.
Await Tasks.Task.WhenAny(Tasks.Task.WhenAll(TaskCollection), XXX)
You can cancel an asynchronous operation after a period of time by using the CancellationTokenSource. CancelAfter method if you don't want to wait for the operation to finish.
WhenAll the task complete is executed before the other tasks are completed. This means that Task. WhenAll doesn't block the execution.
CancellationToken is immutable and must be canceled by calling CancellationTokenSource. cancel() on the CancellationTokenSource that creates it. It can only be canceled once. If canceled, it should not be passed to future operations.
Use TaskCompletionSource<T>
to create a task for some asynchronous condition that does not already have an asynchronous API. Use CancellationToken.Register
to hook the modern CancellationToken-based cancellation system into another cancellation system. Your solution just needs to combine these two.
I have a CancellationToken.AsTask()
extension method in my AsyncEx library, but you can write your own as such:
<System.Runtime.CompilerServices.Extension> _
Public Shared Function AsTask(cancellationToken As CancellationToken) As Task
Dim tcs = New TaskCompletionSource(Of Object)()
cancellationToken.Register(Function() tcs.TrySetCanceled(), useSynchronizationContext := False)
Return tcs.Task
End Function
Usage is as you expected:
Await Task.WhenAny(Task.WhenAll(taskCollection), cancellationToken.AsTask())
Dim tcs as new TaskCompletionSource(Of Object)()
Await Tasks.Task.WhenAny(Tasks.Task.WhenAll(TaskCollection), tcs)
To cancel, call tcs.SetResult(Nothing). This will fire your Task.WhenAny.
More elegant from my opinion :
await Task.Run(()=> Task.WaitAll(myArrayOfTasks), theCancellationToken);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With