简体   繁体   English

如何取消可在多点取消的长时间运行操作?

[英]How to cancel a long-running operation that can be cancelled at many points?

We have a long-running operation comprised of many points at which it can be cancelled. 我们有一个长期运行的操作,包括许多可以取消的点。 If we were to use the task cancellation token approach, we would need to make sure that we check for cancellation at every required place. 如果我们要使用任务取消令牌方法,我们需要确保在每个所需位置检查取消。

This seems suboptimal to us. 这对我们来说似乎不是最理想的。 We see two problems here: 我们在这里看到两个问题:

  1. we need to make a cancellation token check at every place where there is opportunity for cancellation which we feel clutters the code and there is a potential to miss points in the code at which there are other opportunities for cancellation. 我们需要在每个有取消机会的地方进行取消令牌检查,我们觉得这些地方会使代码混乱,并且有可能错过代码中有其他取消机会的点数。
  2. if we follow the guideline to avoid global variables, we need to pass the cancellation token as a parameter to many methods which we feel is repetitive and clutters the code. 如果我们遵循指南以避免全局变量,我们需要将取消令牌作为参数传递给许多方法,我们认为这些方法是重复的并且使代码混乱。

Should we use a global cancellation token to deal with 2.? 我们应该使用全局取消令牌来处理2.? Should we use AppDomain to deal with 1. and 2.? 我们应该使用AppDomain来处理1.和2.?

we would need to make sure that we check for cancellation at every required place. 我们需要确保在每个要求的地方检查取消。

This is really the proper way to handle this. 这是处理这个问题的正确方法。

A global token doesn't solve checking at each required place, and would only potentially help with not passing around tokens as parameters to the methods. 全局令牌不能解决每个所需位置的检查问题,并且只能帮助不将令牌作为参数传递给方法。 It does limit you - if you use a global token, you take away the ability to now, or in the future, modify your routine to have multiple operations in flight with separate cancellation. 它确实限制了您 - 如果您使用全局令牌,则会剥夺现在或将来修改您的例程以在单独取消时进行多个操作的能力。

However, I would argue that passing the token around is actually a good thing. 但是,我认为传递令牌实际上是一件好事。 This makes your API self-documenting - each method which accepts a token is something which may, potentially, raise a OperationCanceledException and supports cancellation. 这使得您的API自我记录 - 每个接受令牌的方法都可能引发OperationCanceledException并支持取消。

Any other approach that avoids these issues is going to require a model for cancellation that is not cooperative. 避免这些问题的任何其他方法都需要一个不合作的取消模型。 This has detrimental side effects, as forcibly "killing" running operations is rarely a good thing (for example, there are many reasons to avoid Thread.Abort that are easy to find). 这有不利的副作用,因为强行“杀死”运行操作很少是好事(例如,有很多理由可以避免易于查找的Thread.Abort)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM