我一直在看到在Cancellation.Register
结果上使用using
子句的CancellationTokenRegistration
的代码:
using (CancellationTokenRegistration ctr = token.Register(() => wc.CancelAsync()))
{
await wc.DownloadStringAsync(new Uri("http://www.hamster.com"));
}
我知道您应该确保将
Dispose
设为IDisposable
,但是为什么它甚至实现了IDisposable
呢?它必须释放哪些资源?它唯一考虑平等的方法。如果您不使用
Dispose
怎么办?你漏什么? 最佳答案
此模式是确保自动调用CancellationTokenRegistration.Unregister()
的便捷方法。 Stephen Toub在Parallel Programming with .NET博客文章中经常使用它,例如here。
IMO,对此的最佳答案可以在Microsoft的Mike Liddell的.NET 4 Cancellation Framework帖子中找到:
Mike Liddell的另一个相关文档是"Using Cancellation Support in .NET Framework 4" (UsingCancellationinNET4.pdf)。
更新了,这是可验证的here in the Reference Source。
还需要注意的是,取消回调是使用CancellationTokenSource
注册的,而不是使用CancellationToken
注册的。因此,如果CancellationTokenRegistration.Dispose()
的作用域不正确,则该注册将在父CancellationTokenSource
对象的生存期内保持 Activity 状态。当异步操作的范围结束时,这可能导致意外的回调,例如:
async Task TestAsync(WebClient wc, CancellationToken token)
{
token.Register(() => wc.CancelAsync());
await wc.DownloadStringAsync(new Uri("http://www.hamster.com"));
}
// CancellationTokenSource.Cancel() may still get called later,
// in which case wc.CancelAsync() will be invoked too
因此,将一次性
CancellationTokenRegistration
与using
范围合并(或使用CancellationTokenRegistration.Dispose()
显式调用try/finally
)是很重要的。