如何取消 CancellationToken
Posted
技术标签:
【中文标题】如何取消 CancellationToken【英文标题】:How to cancel a CancellationToken 【发布时间】:2015-09-01 17:25:31 【问题描述】:我启动一个任务,然后启动其他任务等等。鉴于该树,如果任何任务失败,则整个操作的结果将毫无用处。我正在考虑使用取消令牌。令我惊讶的是,令牌没有“CancelThisToken()”方法...
我只有一个CancellationToken,如何取消它?
【问题讨论】:
您正在寻找 CancellationTokenSource msdn.microsoft.com/en-us/library/… @CoderDennis 我不明白如何获得仅给定令牌的令牌源... 如果您没有CancellationTokenSource
,则无法取消它。令牌是所有线程共享的对象,该对象由CancellationTokenSource.Cancel()
方法设置。一旦这样做,CancellationToken.IsCancellationRequested
将是真的。在那之前,它永远都是假的。 (不能直接设置。)如果你没有CancellationTokenSource
,那么没有什么可以抛出取消。你需要 CancellationTokenSource
来取消这样的线程。
【参考方案1】:
根据文档状态,您需要从源对象调用 cancel 方法。示例代码包含在您提供的链接中。以下是相关部分:
// Define the cancellation token.
CancellationTokenSource source = new CancellationTokenSource();
previouslyProvidedToken = source.Token;
...
source.Cancel();
CancellationToken Struct
如果我只有一个 CancellationToken,我该如何取消它?
编辑:这是我几年前写的,现在重新审视它,我不知道它在写时或现在是否真的有效。保留原样以供后代使用。
如果不引用源,您将无法取消令牌。这并不意味着您需要首先生成令牌的CancellationTokenSource
。当给定CancellationToken
时,您可以创建令牌源的新实例,将其令牌分配给提供的令牌,然后取消它。可以读取此令牌的所有其他方都将看到已请求取消它。
【讨论】:
@Leonardo,您应该首先创建令牌源,然后从中请求令牌。查看我提供的链接中的示例代码 这是我在工作中用于备份实用程序的方法 - 如果任何Task
失败,我的结果也将毫无用处。 (两个数据库,一个 SQL,一个 AS/400 DB2,不同步,这是不可接受的。所以如果出现任何故障,我会丢弃所有数据。)
@Leonardo 如果只给出令牌,您无法获取源。 按照设计,当您拥有的只是该令牌时,您无法取消该令牌。如果可以的话,这将是一个破碎的系统。
@RyanS 我的意思是你应该将Servy的信息(或我的)添加到答案中。
在编辑中重写 previouslyProvidedToken
是一种不好的做法...如果提供的令牌的源被取消(在树中的更高级别),这在功能上不会对该取消做出反应.在这种情况下,传递 CancellationToken 完全没用,因此 Daniel Park 的回答提供了更好的解决方案。【参考方案2】:
作为迄今为止提供的答案的扩展,如果您希望为您的方法提供CancellationToken
实例,和在内部取消,您应该检查CancellationTokenSource.CreateLinkedTokenSource
。
本质上,这将在调用 cts.Cancel()
或其提供的令牌之一时取消。
【讨论】:
【参考方案3】:令牌使您有权知道有人试图取消某事。它不赋予您实际发出取消信号的权利。只有取消令牌源才能为您提供。这是设计使然。
【讨论】:
也许直接解决问题?我认为答案是“你不能”(?)【参考方案4】:从CancellationTokenSource
实例生成CancellationToken
实例并在CTS 实例上调用Cancel
。
例如:Cancel()
还有一种方法可以优雅地取消线程而不触发异常。只需检查IsCancellationRequested
的 CT 并自行处理此案。
更多信息:Use of IsCancellationRequested property?
【讨论】:
那么当你被提供一个时,你就可以控制取消。您可以密切关注 IsCancellationRequested,也可以依靠框架在您的线程上抛出异常来强制执行此操作。以上是关于如何取消 CancellationToken的主要内容,如果未能解决你的问题,请参考以下文章
取消 HttpClient 请求 - 为啥 TaskCanceledException.CancellationToken.IsCancellationRequested 为假?
C#源码生成器的cancellationtoken啥时候取消?
使用 CancellationToken 取消任务而不在任务中明确检查?
NamedPipeServerStream.ReadAsync() 在 CancellationToken 请求取消时不退出