2

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

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

  1. 除了 BeginDoSomething 和 EndDoSomething 之外,还有一个 CancelDoSomething 方法。这不是常见的 asaync 模式,因此操作的用户不容易发现。
  2. 根据没有。1:有一个 Cancel 属性
  3. BeginDoSomething 返回的 IAsyncResult 实例可以强制转换为 DoSomethingAsyncResult。DoSomethingAsyncResult 有一个 Cancel 方法。同样,这不是异步模式的常见用法,对于类库的“普通用户”来说几乎不知道。
  4. 根据没有。3:有一个 Cancel 属性
  5. BeginDoSomething 返回的 IAsyncResult 实例实现了 IAbortableAsyncResult: public IAbortableAsyncResult:IAsyncResult { void Abort(); }。对我来说,这似乎是最优雅的方式。当用户使用 BeginDoSomething 开始操作时,他会得到一个 IAbortableAsyncResult 的实例,这意味着向他突出介绍了这个特殊功能。

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

[编辑]

一种不依赖于 TPL/.NET 4 的方法值得赞赏,因为它有一个解决方案,它也适用于无法移植到最新版本的 .NET 框架的遗留代码。

[/编辑]

4

1 回答 1

3

CancellationToken 和 CancellationTokenSource 在 4.0 中被添加到 .net,并从此成为通用取消模式的基础。通常,异步方法具有采用 CancellationToken 的重载。

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

CancellationToken 是异步任务使用的接口,任务的发起者使用一个 CancellationTokenSource 发出这个令牌,以后可能会取消它。

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

于 2011-12-01T10:19:14.017 回答