取消异步操作

时间:2011-12-01 10:08:51

标签: .net asynchronous class-design iasyncresult

我正在开发一个实现协议栈的类库。我有一个实现IAsyncResult的异步操作DoSomething。此方法的用户可以使用BeginDoSomething和EndDoSomething。这么长时间,这是一项非常普遍的任务。

现在我得到了使异步操作中止的要求。我可以想到几种方法来实现这一点,但我不确定哪一种是最好的:

  1. 除了BeginDoSomething和EndDoSomething之外,还有一个CancelDoSomething方法。这不是常见的asaync模式,因此不容易找到操作的用户。
  2. 根据没有。 1:有取消财产
  3. BeginDoSomething返回的IAsyncResult实例可以转换为DoSomethingAsyncResult。 DoSomethingAsyncResult有一个Cancel方法。同样,这不是异步模式的常见用法,也很难知道类库的“普通用户”。
  4. 根据没有。 3:拥有取消财产
  5. BeginDoSomething返回的IAsyncResult实例实现了IAbortableAsyncResult:public IAbortableAsyncResult:IAsyncResult { void Abort(); }。对我来说,这似乎是最优雅的方式。当用户使用BeginDoSomething启动操作时,他获得了一个IAbortableAsyncResult实例,这意味着这个特殊功能被突出地介绍给他。
  6. 什么是最佳解决方案?还有更多方法可以解决这个问题吗?我不喜欢。因为它没有代码气味(至少我直到现在才认识到)。

    [编辑]

    一种不依赖于TPL / .NET 4的方法被认为有一种解决方案也适用于无法移植到最新版.NET Framework的遗留代码。

    [/ EDIT]

1 个答案:

答案 0 :(得分:3)

CancellationToken和CancellationTokenSource已添加到4.0中的.net,并构成了此后常见取消模式的基础。通常,异步方法有一个需要CancellationToken的重载。

CancellationTokens的消费者可以在取消令牌时注册回调,并使用回调停止执行。或者,如果任务执行时间不是特别长,则可以间歇性地轮询IsCanceled属性。

CancellationToken是异步任务使用的接口,任务的发起者使用CancellationTokenSource发出此令牌,然后可能在将来取消它。

除了成为取消取消的标准方法之外,这种方法的一个好处是它可以组合。如果任务组成了其他几个可取消的异步操作,则可以将相同的取消令牌传递给它们,并且取消应该自动完成。