.net 如何取消Task.WhenAll?

avkwfej4  于 2023-10-21  发布在  .NET
关注(0)|答案(4)|浏览(119)

当前正在使用下面的代码等待任务集合完成。然而,我现在有一种情况,我希望能够取消/中止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)

我假设它会沿着下一段代码的行,但我不确定“XXX”会发生什么。

Await Tasks.Task.WhenAny(Tasks.Task.WhenAll(TaskCollection), XXX)
c3frrgcw

c3frrgcw1#

使用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())
bvpmtnay

bvpmtnay2#

Dim tcs as new TaskCompletionSource(Of Object)()
Await Tasks.Task.WhenAny(Tasks.Task.WhenAll(TaskCollection), tcs)

若要取消,请调用tcs.SetResult(Nothing)。这将触发您的Task.WhenAny.

q35jwt9p

q35jwt9p3#

在我看来更优雅:

await Task.Run(()=> Task.WaitAll(myArrayOfTasks), theCancellationToken);
bq9c1y66

bq9c1y664#

在.NET 6(或更高版本)中,您现在可以使用:用途:

Await Task.WhenAll(...).WaitAsync(cancellationToken)

WaitAsync可以接受TimeSpan timeoutCancellationToken或两者。

相关问题