我目前有一个应用程序,其中我创建了一系列任务,这些任务按顺序执行,具有可以在任务之间中断执行的取消源(即在安全终止点)。我目前仅在管理类被处理时使用此取消源,作为一种清洁且快速中止执行的方式。
现在,我有一个用例,我希望创建一个自动超时以取消任务序列,以防操作员未能及时响应(一些任务等待操作员与物理机构交互)。同时,如果管理类被处理,我仍然需要支持取消。我找到了CancellationTokenSource.CreateLinkedTokenSource,听起来像是我需要的,但我有一些顾虑:
现在,我有一个用例,我希望创建一个自动超时以取消任务序列,以防操作员未能及时响应(一些任务等待操作员与物理机构交互)。同时,如果管理类被处理,我仍然需要支持取消。我找到了CancellationTokenSource.CreateLinkedTokenSource,听起来像是我需要的,但我有一些顾虑:
多个任务系列可以并行执行,因此我需要为超时取消创建一个新的CancellationTokenSource,并为每个开始的任务系列创建一个相关联的链接源。CancellationTokenSource实现IDisposable,这意味着我需要保留取消源并在最后一个任务完成或任何子任务被取消或出错时进行Dispose。即使有匿名方法闭包的帮助,这似乎仍然很笨拙(取消源仍然在传递)。
我还需要防止在计时器到期之前取消源被Dispose(以便我不会取消已经Dispose的源)。这是潜在的竞争条件,所以我需要添加适当的锁定。这看起来也很笨拙,增加了显著的复杂性(未来的维护成本),并使单元测试更具挑战性(竞争条件很难可靠地引发)。
我是否正在正确的道路上,或者有没有更简单的方法来解决这个问题?
CancellationTokenSource.Dispose()
的MSDN文档明确指出,您应该始终调用Dispose(); 这可能只是通用措辞,但这表明.NET团队没有在这个类中留下Dispose()“可选”的合同义务。http://msdn.microsoft.com/en-us/library/dd321505.aspx - Dan BryantIDisposable
接口的对象,如果你不调用Dispose()
方法,它会被终结器自动"清理"。我认为你应该总是尽量调用任何IDisposable
对象的Dispose()
方法,但在某些情况下,这样做可能会比仅仅依靠终结器更糟糕。TPL就是其中一个模糊的领域 - 在我看来,通常最好不要Dispose()
TPL对象,因为执行这些操作很可能引入维护问题和错误。 - Reed Copsey