6

我目前有一个应用程序,我在其中创建了一系列一个接一个地执行的任务,并带有一个可以中断任务之间执行的取消源(即在安全终止点)。我目前仅在管理类 Disposed 时才使用此取消源,作为一种干净、快速地中止执行的方法。

我现在有一个用例,我想创建一个自动超时来取消任务序列,以防操作员没有及时响应(一些任务等待操作员与物理机制的交互。)在同时,如果管理类是 Disposed,我仍然需要支持取消。我找到了CancellationTokenSource.CreateLinkedTokenSource,这听起来像是我需要的,但我有一些担忧:

  1. 多个任务系列可以并行执行,因此我需要为超时取消创建一个新的 CancellationTokenSource,并为我开始的每个任务系列创建一个关联的链接源。CancellationTokenSource 实现 IDisposable,这意味着我需要保留两个取消源并在最后一个任务完成或任何子任务被取消或故障时处置它们。这似乎相当尴尬,即使有匿名方法闭包的有用魔法(仍然有这些取消源被传递。)

  2. 我还需要防止在计时器到期之前 Disposed 取消源的情况(所以我不取消 Disposed 源。)这是一个潜在的竞争条件,所以我需要添加适当的锁定。这似乎也很尴尬,增加了显着的复杂性(未来的维护成本)并使单元测试更具挑战性(竞争条件很难可靠地诱导。)

我是在走正确的道路还是有更简单的方法来做到这一点?

4

1 回答 1

9

您问题中的核心问题似乎与调用Dispose()您的Task和/或CancellationTokenSource对象有关。在这种情况下,我建议不要调用Dispose这些,这将大大简化您的设计。

作为理由,我将向您推荐此线程。特别是,Stephen Toub(负责 Task 的 PM)建议您应该:

如果根据代码结构简单且正确地进行处理,则积极处置。如果您开始不得不为了 Dispose 进行奇怪的旋转(或者在任务的情况下,使用额外的同步来确保它是安全的,因为 Dispose 只能在任务完成后使用),最好依靠完成照顾事情。

这听起来就像他在最后描述的确切情况——你试图做奇怪的旋转来调用Dispose()这些物体。

于 2011-06-07T17:21:55.720 回答