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?
Currenly使用以下代码等待完成任务集合。但是,我现在有一种情况,我希望能够通过取消令牌取消/中止WhenAll调用。我该怎么办呢?
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'.
我假设它会继续下一行代码,但我不确定'XXX'会发生什么。
Await Tasks.Task.WhenAny(Tasks.Task.WhenAll(TaskCollection), XXX)
4 个解决方案
#1
19
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.
使用TaskCompletionSource
I have a CancellationToken.AsTask()
extension method in my AsyncEx library, but you can write your own as such:
我的AsyncEx库中有一个CancellationToken.AsTask()扩展方法,但您可以自己编写:
<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())
#2
3
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.
要取消,请调用tcs.SetResult(Nothing)。这将触发你的Task.WhenAny。
#3
0
You can also await a delay:
您也可以等待延迟:
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(1000));
#4
0
More elegant from my opinion :
我认为更优雅:
await Task.Run(()=> Task.WaitAll(myArrayOfTasks), theCancellationToken);
#1
19
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.
使用TaskCompletionSource
I have a CancellationToken.AsTask()
extension method in my AsyncEx library, but you can write your own as such:
我的AsyncEx库中有一个CancellationToken.AsTask()扩展方法,但您可以自己编写:
<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())
#2
3
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.
要取消,请调用tcs.SetResult(Nothing)。这将触发你的Task.WhenAny。
#3
0
You can also await a delay:
您也可以等待延迟:
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(1000));
#4
0
More elegant from my opinion :
我认为更优雅:
await Task.Run(()=> Task.WaitAll(myArrayOfTasks), theCancellationToken);