gpt4 book ai didi

c# - 为什么 CancellationTokenRegistration 存在以及它为什么实现 IDisposable

转载 作者:IT王子 更新时间:2023-10-29 04:49:37 27 4
gpt4 key购买 nike

我一直看到在 CancellationTokenRegistration 结果上使用 Cancellation.Registerusing 子句的代码:

using (CancellationTokenRegistration ctr = token.Register(() => wc.CancelAsync()))
{
await wc.DownloadStringAsync(new Uri("http://www.hamster.com"));
}

我知道你应该确保你 Dispose 一个 IDisposable,但为什么它甚至实现了 IDisposable?它必须释放什么资源?它唯一的方法是考虑平等。

如果您不处置它会怎样?你泄露了什么?

最佳答案

此模式是确保自动调用 CancellationTokenRegistration.Unregister() 的便捷方式。它经常被 Stephen Toub 在他的 Parallel Programming with .NET 中使用。博客文章,例如here .

I get that you should make sure you Dispose an IDisposable, but whydoes it even implements IDisposable? what resources does it have torelease? The only methods it has regard equality.

IMO,最好的答案可以在 .NET 4 Cancellation Framework 中找到Microsoft 的 Mike Liddell 发表的文章:

When a callback is registered to a CancellationToken, the currentthread's ExecutionContext is captured so that the callback will be runwith the the exact same security context . The capturing of thecurrent thread's synchronization context is optional can be requestedvia an overload of ct.Register() if required. Callbacks are normallystored and then run when cancellation is requested, but if a callbackis registered after cancellation has been requested, the callback willrun immediately on the current thread, or via Send() on the currentSynchronizationContext if applicable.

When a callback is registered to a CancellationToken, the returnedobject is a CancellationTokenRegistration. This is a light struct typethat is IDiposable, and disposing this registration object causes thecallback to be deregistered. A guarantee is made that after theDispose() method has returned, the registered callback is neitherrunning nor will subsequently commence. A consequence of this is thatCancellationTokenRegistration.Dispose() must block if the callback iscurrently executing. Hence, all registered callbacks should be fastand not block for any significant duration.

Mike Liddell 的另一个相关文档是 "Using Cancellation Support in .NET Framework 4" (UsingCancellationinNET4.pdf) .

已更新,这是可验证的here in the Reference Source .

同样重要的是要注意,取消回调是通过 CancellationTokenSource 注册的,而不是通过 CancellationToken 注册的。因此,如果 CancellationTokenRegistration.Dispose() 的范围不正确,则注册将在父 CancellationTokenSource 对象的生命周期内保持事件状态。当异步操作的范围结束时,这可能会导致意外回调,例如:

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

因此,使用 using(或使用 try/终于).

关于c# - 为什么 CancellationTokenRegistration 存在以及它为什么实现 IDisposable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21367695/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com