取消异步操作
问题描述:
我正在开发一个实现协议栈的类库。在那里我有一个实现IAsyncResult的异步操作DoSomething。此方法的用户可以使用BeginDoSomething和EndDoSomething。只要这是一个很普遍的任务。取消异步操作
现在我得到了使异步操作中止的要求。我能想到的几种方法来实现这一点,但我不知道哪一个是最好的:
- 有除了BeginDoSomething和EndDoSomething一个CancelDoSomething方法。这不是常见的asaync模式,因此不容易找到操作的用户。
- 根据没有。 1:有取消属性
- 由BeginDoSomething返回的IAsyncResult实例可以被转换为DoSomethingAsyncResult。 DoSomethingAsyncResult有一个Cancel方法。再一次,这不是异步模式的常见用法,也很难知道类库的“普通用户”。
- 根据没有。 3:有取消属性
- BeginDoSomething返回的IAsyncResult实例实现IAbortableAsyncResult:
public IAbortableAsyncResult:IAsyncResult { void Abort(); }
。对我来说,这似乎是最优雅的方式。当用户使用BeginDoSomething开始操作时,他会得到一个IAbortableAsyncResult的实例,这意味着这个特殊功能会突出地介绍给他。
什么是最佳解决方案?有更多的方法可以解决这个问题吗?我更喜欢不。 5,因为它没有代码味道(至少我现在还没有认出)。
[编辑]
不依赖于TPL/.NET 4的一种方法被理解为具有一个解决方案,也适用于不能被移植到.NET架构中的最新版本的旧代码。
[/编辑]
答
加入的CancellationToken和CancellationTokenSource在4.0到.NET,并从此形成用于共同消除图案的基础。一般来说,异步方法有一个需要CancellationToken的重载。
CancellationTokens的使用者可以在令牌被取消时注册回调,并使用回调来停止执行。或者,如果任务不是特别长时间执行,则可以间歇性地查询IsCanceled属性。
CancellationToken是异步任务使用的接口,任务的发起者使用CancellationTokenSource发出此令牌,并可能在将来取消它。
这种方法的好处之一,除了它成为一种解决方法的标准方法之外,它是可组合的。如果任务组合了其他几个可取消的异步操作,则可以将相同的取消令牌传递给它们,并且取消应该自动生效。
感谢您的回答。我知道TPL,它是取消功能。对不起,我没有提到这个问题。我更多地寻找一种解决方案,它不会使用.NET 4功能,但更适用于传统代码。 – PVitt
当我在TPL中看到它时,我非常喜欢这种模式,所以当我不得不在紧凑框架中编写类似的代码时,我只是将模式移植到了其中。尽管TPL中的实施经过了高度优化,但您没有理由不能在传统设置中推出自己的版本以达到相同的目的。 –
嗯,好主意。还没有想到它。 – PVitt