我使用一个取消令牌,以便我的服务可以被干净地关闭。该服务具有保持尝试连接到其他服务的逻辑,因此这个令牌是退出在不同线程中运行的重试循环的好方法。我的问题是,我需要调用一个具有内部重试逻辑的服务,但如果重试失败,则在设定的时间后返回。我想创建一个带有超时的新取消令牌来为我完成这个操作。问题在于,我的新令牌未与“主”令牌链接在一起,因此当主令牌被取消时,我的新令牌仍将存活,直到它超时或连接成功并返回。我想要做的是将这两个令牌链接在一起,以便当主令牌被取消时,我的新令牌也会被取消。我尝试使用CancellationTokenSource.CreateLinkedTokenSource方法,但当我的新令牌超时时,它也取消了主令牌。是否有一种方法来处理令牌所需的内容,或者需要更改重试逻辑(可能无法轻松实现这一点)?
这是我想做的事情: 主令牌-传递给各种功能,以便该服务可以干净地关闭。 临时令牌-传递给单个函数,并设置为一分钟后超时。 如果主令牌被取消,临时令牌也必须被取消。 当临时令牌过期时,它不应取消主令牌。
这是我想做的事情: 主令牌-传递给各种功能,以便该服务可以干净地关闭。 临时令牌-传递给单个函数,并设置为一分钟后超时。 如果主令牌被取消,临时令牌也必须被取消。 当临时令牌过期时,它不应取消主令牌。
try { doSomething(ct: childCts.Token); } catch (OperationCancelledException) when (childCts.IsCancellationRequested) {}
。你可以把它放在重试循环中,并在循环内创建子令牌源。然后,当父令牌取消时,它会一直向上冒泡,但当子令牌取消时,只是进行重试。我无法从你的评论中确定你是否已经正确地执行了这个操作;-)。 - binkiOperationCancelledException
有自己的CancellationToken
属性,你应该使用catch (ex) when (condition)
的方式进行检查。这样你就可以确保已经捕获了正确的取消操作。 - AgentFireusing var childCts =
就可以解决问题。 - MattCancellationToken
属性存在的问题是,你的取消令牌的使用者可以创建自己的关联 CTS。在这种情况下,即使你的 CTS 导致了取消,异常也会说不是你而是某个未知的令牌。你能做的最好的事情就是检查你的 CTS 是否为IsCancellationRequested
并假设没有独立于你的源的隐藏取消。(如果有人让一个OperationCanceledException
传播而调用者没有请求它,我会说这是一个 bug。) - relatively_random