.net 如何将CancellationToken与Tasks.WaitAll()一起使用
我想知道如何使用.net 如何将CancellationToken与Tasks.WaitAll()一起使用,.net,asynchronous,async-await,cancellation,.net,Asynchronous,Async Await,Cancellation,我想知道如何使用Task.WaitAll重载,该重载将CancellationToken作为参数,例如 文档中说,CancellationToken参数是“等待任务完成时要观察的CancellationToken。” 既然Task.WaitAll是一个阻塞操作,您怎么可能在该操作期间“观察”它呢?此外,它还表示“cancellationToken参数用于取消等待操作。如果取消,等待将返回false。”但在其他地方,它还表示当取消cancellationToken时会抛出操作CanceledExc
Task.WaitAll
重载,该重载将CancellationToken
作为参数,例如
文档中说,CancellationToken
参数是“等待任务完成时要观察的CancellationToken。”
既然Task.WaitAll
是一个阻塞操作,您怎么可能在该操作期间“观察”它呢?此外,它还表示“cancellationToken参数用于取消等待操作。如果取消,等待将返回false。”但在其他地方,它还表示当取消cancellationToken
时会抛出操作CanceledException
,意思是Task.WaitAll
不会返回true
或false
我要么错过了一些非常简单的东西,要么文档有问题。不管怎样,我都完全糊涂了。我的最终目标是能够等待多个任务完成,或者在特定时间段内无法完成的情况下(通过正确使用CancellationToken
)优雅地取消它们
这与我的文章有关,但这次,我正在编写异步代码,可以观察取消标记
既然Task.WaitAll是一个阻塞操作,那么您怎么可能在该操作期间“观察”它呢
你不是观察它的人;这是Task.WaitAll
方法的作用
此外,它还表示“cancellationToken参数用于取消等待操作。如果取消,等待将返回false”。但在其他地方,它还表示取消cancellationToken时会抛出OperationCanceledException,这意味着Task.WaitAll不返回true或false
这似乎是文档中的一个错误。如果指定的超时时间在任务完成或等待取消之前过去,则返回false
谁取消了
通常,一些代码在另一个线程上运行,因为当前线程已经在忙着等待任务完成。或者您可以调用
CancellationTokenSource.CancelAfter
来指定一个超时,在该超时之后,令牌将被取消。Task.WaitAll
正在观察您传递给它的令牌。@CodesInChaos——那么它是如何被取消的呢?谁取消它?请注意,取消WaitAll
不会取消单个任务。您还需要将令牌传递给任务,并且根据任务的性质,任务还需要显式检查令牌是否已被取消。“谁取消它?”--谁调用其源上的CancellationTokenSource.Cancel()
。对于超时,这是通过源创建的计时器实现的。@roryap主线程不能取消任务。它可以是任何线。确切地说,凡是引用了CancellationTokenSource
的人都可以取消它。这不一定是主线。谢谢,这很有帮助。我遇到的一个问题是,我已经通过生成一个取消令牌的新线程对此进行了测试,并引发了一个异常,而不是Task.WaitAll
返回false。这就是文档的实际问题吗?它说它将返回false,但这不是因为异常。@roryap,基本上是的。文件是错的,很容易核实。我已经向他们的反馈系统报告过了,希望他们能在某个时候修复它。如果令牌被取消,它会抛出异常(即使取消是由于超时)。如果传递给WaitAll的超时在任何令牌被取消或所有任务完成之前过期,则只返回false。@CodesInChaos--“如果传递给WaitAll的超时在任何令牌被取消或所有任务完成之前过期,则只返回false。”--那么您在中指的是什么超时“如果令牌已被取消(即使取消是由于超时),它将引发异常。”@roryap您可以(可选)将超时传递给CancellationTokenSource
,并将单独的超时传递给WaitAll
。前者导致异常,后者导致false
。