vb.net 如何取消 Task.WhenAll?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27238232/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I cancel Task.WhenAll?
提问by iguanaman
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?
目前使用以下代码等待任务集合完成。但是,我现在有一种情况,我希望能够取消/中止 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)
回答by Stephen Cleary
Use TaskCompletionSource<T>to create a task for some asynchronous condition that does not already have an asynchronous API. Use CancellationToken.Registerto hook the modern CancellationToken-based cancellation system into another cancellation system. Your solution just needs to combine these two.
使用TaskCompletionSource<T>创造不已经有一个异步API一些异步状态的任务。用于CancellationToken.Register将现代基于 CancellationToken 的取消系统挂接到另一个取消系统中。您的解决方案只需要将这两者结合起来。
I have a CancellationToken.AsTask()extension method in my AsyncEx library, but you can write your own as such:
我的CancellationToken.AsTask()AsyncEx 库中有一个扩展方法,但您可以这样编写自己的扩展方法:
<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())
回答by Jonathan Allen
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。
回答by Artaban
More elegant from my opinion :
我认为更优雅:
await Task.Run(()=> Task.WaitAll(myArrayOfTasks), theCancellationToken);
回答by Rbjz
You can also await a delay:
您还可以等待延迟:
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(1000));

