如何取消Task.WhenAll?

时间:2022-08-23 17:52:04

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 为某些尚未具有异步API的异步条件创建任务。使用CancellationToken.Register将现代基于CancellationToken的取消系统挂钩到另一个取消系统。您的解决方案只需要将这两者结合起来。

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 为某些尚未具有异步API的异步条件创建任务。使用CancellationToken.Register将现代基于CancellationToken的取消系统挂钩到另一个取消系统。您的解决方案只需要将这两者结合起来。

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