2011-12-01 115 views
2

我正在开发一个实现协议栈的类库。在那里我有一个实现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的实例,这意味着这个特殊功能会突出地介绍给他。

什么是最佳解决方案?有更多的方法可以解决这个问题吗?我更喜欢不。 5,因为它没有代码味道(至少我现在还没有认出)。

[编辑]

不依赖于TPL/.NET 4的一种方法被理解为具有一个解决方案,也适用于不能被移植到.NET架构中的最新版本的旧代码。

[/编辑]

回答

3

加入的CancellationToken和CancellationTokenSource在4.0到.NET,并从此形成用于共同消除图案的基础。一般来说,异步方法有一个需要CancellationToken的重载。

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

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

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

+0

感谢您的回答。我知道TPL,它是取消功能。对不起,我没有提到这个问题。我更多地寻找一种解决方案,它不会使用.NET 4功能,但更适用于传统代码。 – PVitt

+0

当我在TPL中看到它时,我非常喜欢这种模式,所以当我不得不在紧凑框架中编写类似的代码时,我只是将模式移植到了其中。尽管TPL中的实施经过了高度优化,但您没有理由不能在传统设置中推出自己的版本以达到相同的目的。 –

+0

嗯,好主意。还没有想到它。 – PVitt