CancellationTokenRegistration

CancellationTokenRegistration

我一直在看到在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

因此,将一次性CancellationTokenRegistrationusing范围合并(或使用CancellationTokenRegistration.Dispose()显式调用try/finally)是很重要的。

10-06 02:40