如何取消Task.WhenAll?

时间:2014-12-01 22:06:03

标签: .net vb.net task-parallel-library

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)

4 个答案:

答案 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));