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)
我假设它会在下一段代码的基础上进行,但是我不确定会发生什么事情&#39; XXX&#39;。< / p>
Await Tasks.Task.WhenAny(Tasks.Task.WhenAll(TaskCollection), XXX)
答案 0 :(得分:19)
使用TaskCompletionSource<T>
为某些尚未拥有异步API的异步条件创建任务。使用CancellationToken.Register
将现代基于CancellationToken的取消系统挂钩到另一个取消系统。您的解决方案只需要将这两者结合起来。
我有CancellationToken.AsTask()
extension method in my AsyncEx library,但您可以自己编写:
<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
用法如您所愿:
Await Task.WhenAny(Task.WhenAll(taskCollection), cancellationToken.AsTask())
答案 1 :(得分:3)
Dim tcs as new TaskCompletionSource(Of Object)()
Await Tasks.Task.WhenAny(Tasks.Task.WhenAll(TaskCollection), tcs)
要取消,请调用tcs.SetResult(Nothing)。这将触发你的Task.WhenAny。
答案 2 :(得分:2)
从我的观点来看更优雅:
await Task.Run(()=> Task.WaitAll(myArrayOfTasks), theCancellationToken);
答案 3 :(得分:0)
您也可以等待延迟:
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(1000));